diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 84dd9885..d54677f7 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -800,6 +800,16 @@ TimelineModel::decryptEvent(const mtx::events::EncryptedEvent<mtx::events::msg::
void
TimelineModel::replyAction(QString id)
{
+ setReply(id);
+ ChatPage::instance()->focusMessageInput();
+}
+
+RelatedInfo
+TimelineModel::relatedInfo(QString id)
+{
+ if (!events.contains(id))
+ return {};
+
auto event = events.value(id);
if (auto e =
std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(&event)) {
@@ -815,10 +825,9 @@ TimelineModel::replyAction(QString id)
related.quoted_formatted_body = mtx::accessors::formattedBodyWithFallback(event);
related.quoted_formatted_body.remove(QRegularExpression(
"<mx-reply>.*</mx-reply>", QRegularExpression::DotMatchesEverythingOption));
- nhlog::ui()->debug("after replacement: {}", related.quoted_body.toStdString());
related.room = room_id_;
- ChatPage::instance()->messageReply(related);
+ return related;
}
void
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 02f5527a..0b181583 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -18,6 +18,7 @@ struct Timeline;
struct Messages;
struct ClaimKeys;
}
+struct RelatedInfo;
namespace qml_mtx_events {
Q_NAMESPACE
@@ -124,6 +125,7 @@ class TimelineModel : public QAbstractListModel
int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
Q_PROPERTY(std::vector<QString> typingUsers READ typingUsers WRITE updateTypingUsers NOTIFY
typingUsersChanged)
+ Q_PROPERTY(QString reply READ reply WRITE setReply NOTIFY replyChanged RESET resetReply)
public:
explicit TimelineModel(TimelineViewManager *manager,
@@ -191,6 +193,7 @@ public:
void addEvents(const mtx::responses::Timeline &events);
template<class T>
void sendMessage(const T &msg);
+ RelatedInfo relatedInfo(QString id);
public slots:
void setCurrentIndex(int index);
@@ -206,6 +209,22 @@ public slots:
}
std::vector<QString> typingUsers() const { return typingUsers_; }
+ QString reply() const { return reply_; }
+ void setReply(QString newReply)
+ {
+ if (reply_ != newReply) {
+ reply_ = newReply;
+ emit replyChanged(reply_);
+ }
+ }
+ void resetReply()
+ {
+ if (!reply_.isEmpty()) {
+ reply_ = "";
+ emit replyChanged(reply_);
+ }
+ }
+
private slots:
// Add old events at the top of the timeline.
void addBackwardsEvents(const mtx::responses::Messages &msgs);
@@ -225,6 +244,7 @@ signals:
void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo);
void eventFetched(QString requestingEvent, mtx::events::collections::TimelineEvents event);
void typingUsersChanged(std::vector<QString> users);
+ void replyChanged(QString reply);
private:
DecryptionResult decryptEvent(
@@ -254,6 +274,7 @@ private:
bool isProcessingPending = false;
QString currentId;
+ QString reply_;
std::vector<QString> typingUsers_;
TimelineViewManager *manager_;
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 794c13aa..0a339825 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -188,8 +188,11 @@ TimelineViewManager::initWithMessages(const std::map<QString, mtx::responses::Ti
}
void
-TimelineViewManager::queueTextMessage(const QString &msg, const std::optional<RelatedInfo> &related)
+TimelineViewManager::queueTextMessage(const QString &msg)
{
+ if (!timeline_)
+ return;
+
mtx::events::msg::Text text = {};
text.body = msg.trimmed().toStdString();
@@ -203,13 +206,15 @@ TimelineViewManager::queueTextMessage(const QString &msg, const std::optional<Re
text.format = "org.matrix.custom.html";
}
- if (related) {
+ if (!timeline_->reply().isEmpty()) {
+ auto related = timeline_->relatedInfo(timeline_->reply());
+
QString body;
bool firstLine = true;
- for (const auto &line : related->quoted_body.split("\n")) {
+ for (const auto &line : related.quoted_body.split("\n")) {
if (firstLine) {
firstLine = false;
- body = QString("> <%1> %2\n").arg(related->quoted_user).arg(line);
+ body = QString("> <%1> %2\n").arg(related.quoted_user).arg(line);
} else {
body = QString("%1\n> %2\n").arg(body).arg(line);
}
@@ -221,17 +226,17 @@ TimelineViewManager::queueTextMessage(const QString &msg, const std::optional<Re
text.format = "org.matrix.custom.html";
if (settings->isMarkdownEnabled())
text.formatted_body =
- utils::getFormattedQuoteBody(*related, utils::markdownToHtml(msg))
+ utils::getFormattedQuoteBody(related, utils::markdownToHtml(msg))
.toStdString();
else
text.formatted_body =
- utils::getFormattedQuoteBody(*related, msg.toHtmlEscaped()).toStdString();
+ utils::getFormattedQuoteBody(related, msg.toHtmlEscaped()).toStdString();
- text.relates_to.in_reply_to.event_id = related->related_event;
+ text.relates_to.in_reply_to.event_id = related.related_event;
+ timeline_->resetReply();
}
- if (timeline_)
- timeline_->sendMessage(text);
+ timeline_->sendMessage(text);
}
void
@@ -247,6 +252,11 @@ TimelineViewManager::queueEmoteMessage(const QString &msg)
emote.format = "org.matrix.custom.html";
}
+ if (!timeline_->reply().isEmpty()) {
+ emote.relates_to.in_reply_to.event_id = timeline_->reply().toStdString();
+ timeline_->resetReply();
+ }
+
if (timeline_)
timeline_->sendMessage(emote);
}
@@ -259,8 +269,7 @@ TimelineViewManager::queueImageMessage(const QString &roomid,
const QString &mime,
uint64_t dsize,
const QSize &dimensions,
- const QString &blurhash,
- const std::optional<RelatedInfo> &related)
+ const QString &blurhash)
{
mtx::events::msg::Image image;
image.info.mimetype = mime.toStdString();
@@ -272,10 +281,13 @@ TimelineViewManager::queueImageMessage(const QString &roomid,
image.info.w = dimensions.width();
image.file = file;
- if (related)
- image.relates_to.in_reply_to.event_id = related->related_event;
+ auto model = models.value(roomid);
+ if (!model->reply().isEmpty()) {
+ image.relates_to.in_reply_to.event_id = model->reply().toStdString();
+ model->resetReply();
+ }
- models.value(roomid)->sendMessage(image);
+ model->sendMessage(image);
}
void
@@ -285,8 +297,7 @@ TimelineViewManager::queueFileMessage(
const std::optional<mtx::crypto::EncryptedFile> &encryptedFile,
const QString &url,
const QString &mime,
- uint64_t dsize,
- const std::optional<RelatedInfo> &related)
+ uint64_t dsize)
{
mtx::events::msg::File file;
file.info.mimetype = mime.toStdString();
@@ -295,10 +306,13 @@ TimelineViewManager::queueFileMessage(
file.url = url.toStdString();
file.file = encryptedFile;
- if (related)
- file.relates_to.in_reply_to.event_id = related->related_event;
+ auto model = models.value(roomid);
+ if (!model->reply().isEmpty()) {
+ file.relates_to.in_reply_to.event_id = model->reply().toStdString();
+ model->resetReply();
+ }
- models.value(roomid)->sendMessage(file);
+ model->sendMessage(file);
}
void
@@ -307,8 +321,7 @@ TimelineViewManager::queueAudioMessage(const QString &roomid,
const std::optional<mtx::crypto::EncryptedFile> &file,
const QString &url,
const QString &mime,
- uint64_t dsize,
- const std::optional<RelatedInfo> &related)
+ uint64_t dsize)
{
mtx::events::msg::Audio audio;
audio.info.mimetype = mime.toStdString();
@@ -317,10 +330,13 @@ TimelineViewManager::queueAudioMessage(const QString &roomid,
audio.url = url.toStdString();
audio.file = file;
- if (related)
- audio.relates_to.in_reply_to.event_id = related->related_event;
+ auto model = models.value(roomid);
+ if (!model->reply().isEmpty()) {
+ audio.relates_to.in_reply_to.event_id = model->reply().toStdString();
+ model->resetReply();
+ }
- models.value(roomid)->sendMessage(audio);
+ model->sendMessage(audio);
}
void
@@ -329,8 +345,7 @@ TimelineViewManager::queueVideoMessage(const QString &roomid,
const std::optional<mtx::crypto::EncryptedFile> &file,
const QString &url,
const QString &mime,
- uint64_t dsize,
- const std::optional<RelatedInfo> &related)
+ uint64_t dsize)
{
mtx::events::msg::Video video;
video.info.mimetype = mime.toStdString();
@@ -339,8 +354,11 @@ TimelineViewManager::queueVideoMessage(const QString &roomid,
video.url = url.toStdString();
video.file = file;
- if (related)
- video.relates_to.in_reply_to.event_id = related->related_event;
+ auto model = models.value(roomid);
+ if (!model->reply().isEmpty()) {
+ video.relates_to.in_reply_to.event_id = model->reply().toStdString();
+ model->resetReply();
+ }
- models.value(roomid)->sendMessage(video);
+ model->sendMessage(video);
}
diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index 0c516e7f..122e4aec 100644
--- a/src/timeline/TimelineViewManager.h
+++ b/src/timeline/TimelineViewManager.h
@@ -26,8 +26,6 @@ class TimelineViewManager : public QObject
TimelineModel *timeline MEMBER timeline_ READ activeTimeline NOTIFY activeTimelineChanged)
Q_PROPERTY(
bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged)
- Q_PROPERTY(QString replyingEvent READ getReplyingEvent WRITE updateReplyingEvent NOTIFY
- replyingEventChanged)
public:
TimelineViewManager(QSharedPointer<UserSettings> userSettings, QWidget *parent = nullptr);
@@ -52,26 +50,13 @@ signals:
void replyClosed();
public slots:
- void updateReplyingEvent(const QString &replyingEvent)
- {
- if (this->replyingEvent_ != replyingEvent) {
- this->replyingEvent_ = replyingEvent;
- emit replyingEventChanged(replyingEvent_);
- }
- }
- void closeReply()
- {
- this->updateReplyingEvent(nullptr);
- emit replyClosed();
- }
- QString getReplyingEvent() const { return replyingEvent_; }
void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
void initWithMessages(const std::map<QString, mtx::responses::Timeline> &msgs);
void setHistoryView(const QString &room_id);
void updateColorPalette();
- void queueTextMessage(const QString &msg, const std::optional<RelatedInfo> &related);
+ void queueTextMessage(const QString &msg);
void queueEmoteMessage(const QString &msg);
void queueImageMessage(const QString &roomid,
const QString &filename,
@@ -80,29 +65,25 @@ public slots:
const QString &mime,
uint64_t dsize,
const QSize &dimensions,
- const QString &blurhash,
- const std::optional<RelatedInfo> &related);
+ const QString &blurhash);
void queueFileMessage(const QString &roomid,
const QString &filename,
const std::optional<mtx::crypto::EncryptedFile> &file,
const QString &url,
const QString &mime,
- uint64_t dsize,
- const std::optional<RelatedInfo> &related);
+ uint64_t dsize);
void queueAudioMessage(const QString &roomid,
const QString &filename,
const std::optional<mtx::crypto::EncryptedFile> &file,
const QString &url,
const QString &mime,
- uint64_t dsize,
- const std::optional<RelatedInfo> &related);
+ uint64_t dsize);
void queueVideoMessage(const QString &roomid,
const QString &filename,
const std::optional<mtx::crypto::EncryptedFile> &file,
const QString &url,
const QString &mime,
- uint64_t dsize,
- const std::optional<RelatedInfo> &related);
+ uint64_t dsize);
private:
#ifdef USE_QUICK_VIEW
@@ -119,7 +100,6 @@ private:
QHash<QString, QSharedPointer<TimelineModel>> models;
TimelineModel *timeline_ = nullptr;
bool isInitialSync_ = true;
- QString replyingEvent_;
QSharedPointer<UserSettings> settings;
QHash<QString, QColor> userColors;
|