Add initial support for rich replies to nheko

This commit is contained in:
Joseph Donofry 2019-06-09 19:03:18 -04:00
parent 0840f47f83
commit b9dde957a8
No known key found for this signature in database
GPG key ID: E8A1D78EF044B0CB
10 changed files with 65 additions and 9 deletions

4
deps/CMakeLists.txt vendored
View file

@ -46,10 +46,10 @@ set(BOOST_SHA256
set( set(
MTXCLIENT_URL MTXCLIENT_URL
https://github.com/Nheko-Reborn/mtxclient/archive/1c31a8072f09a454b9239e11740473c8a7dbee39.tar.gz https://github.com/Nheko-Reborn/mtxclient/archive/8c6e9ba8fc18ed9dd69d014eebd1ebff08701d6d.tar.gz
) )
set(MTXCLIENT_HASH set(MTXCLIENT_HASH
5cdcd7d6feaefa8df8966bd053ea2d1181eb7e6c0f3b548b2f98f00400e2760e) b31ec18b9d7d74db1a17b930bfa570fa1cede56cc49b43948b7d86c396f2f3d3)
set( set(
TWEENY_URL TWEENY_URL
https://github.com/mobius3/tweeny/archive/b94ce07cfb02a0eb8ac8aaf66137dabdaea857cf.tar.gz https://github.com/mobius3/tweeny/archive/b94ce07cfb02a0eb8ac8aaf66137dabdaea857cf.tar.gz

View file

@ -264,6 +264,11 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
view_manager_, view_manager_,
SLOT(queueTextMessage(const QString &))); SLOT(queueTextMessage(const QString &)));
connect(text_input_,
SIGNAL(sendReplyMessage(const QString &, const QString &)),
view_manager_,
SLOT(queueReplyMessage(const QString &, const QString &)));
connect(text_input_, connect(text_input_,
SIGNAL(sendEmoteMessage(const QString &)), SIGNAL(sendEmoteMessage(const QString &)),
view_manager_, view_manager_,

View file

@ -83,7 +83,7 @@ signals:
void connectionLost(); void connectionLost();
void connectionRestored(); void connectionRestored();
void messageReply(const QString &username, const QString &msg); void messageReply(const QString &username, const QString &msg, const QString &related_event);
void notificationsRetrieved(const mtx::responses::Notifications &); void notificationsRetrieved(const mtx::responses::Notifications &);

View file

@ -398,14 +398,24 @@ FilteredTextEdit::submit()
auto name = text.mid(1, command_end - 1); auto name = text.mid(1, command_end - 1);
auto args = text.mid(command_end + 1); auto args = text.mid(command_end + 1);
if (name.isEmpty() || name == "/") { if (name.isEmpty() || name == "/") {
message(args); if (!related_event_.isEmpty()) {
reply(args, related_event_);
} else {
message(args);
}
} else { } else {
command(name, args); command(name, args);
} }
} else { } else {
message(std::move(text)); if (!related_event_.isEmpty()) {
reply(std::move(text), std::move(related_event_));
} else {
message(std::move(text));
}
} }
related_event_ = "";
clear(); clear();
} }
@ -536,6 +546,7 @@ TextInputWidget::TextInputWidget(QWidget *parent)
connect(sendMessageBtn_, &FlatButton::clicked, input_, &FilteredTextEdit::submit); connect(sendMessageBtn_, &FlatButton::clicked, input_, &FilteredTextEdit::submit);
connect(sendFileBtn_, SIGNAL(clicked()), this, SLOT(openFileSelection())); connect(sendFileBtn_, SIGNAL(clicked()), this, SLOT(openFileSelection()));
connect(input_, &FilteredTextEdit::message, this, &TextInputWidget::sendTextMessage); connect(input_, &FilteredTextEdit::message, this, &TextInputWidget::sendTextMessage);
connect(input_, &FilteredTextEdit::reply, this, &TextInputWidget::sendReplyMessage);
connect(input_, &FilteredTextEdit::command, this, &TextInputWidget::command); connect(input_, &FilteredTextEdit::command, this, &TextInputWidget::command);
connect(input_, &FilteredTextEdit::image, this, &TextInputWidget::uploadImage); connect(input_, &FilteredTextEdit::image, this, &TextInputWidget::uploadImage);
connect(input_, &FilteredTextEdit::audio, this, &TextInputWidget::uploadAudio); connect(input_, &FilteredTextEdit::audio, this, &TextInputWidget::uploadAudio);
@ -653,7 +664,7 @@ TextInputWidget::paintEvent(QPaintEvent *)
} }
void void
TextInputWidget::addReply(const QString &username, const QString &msg) TextInputWidget::addReply(const QString &username, const QString &msg, const QString &replied_event)
{ {
input_->setText(QString("> %1: %2\n\n").arg(username).arg(msg)); input_->setText(QString("> %1: %2\n\n").arg(username).arg(msg));
input_->setFocus(); input_->setFocus();
@ -661,4 +672,5 @@ TextInputWidget::addReply(const QString &username, const QString &msg)
auto cursor = input_->textCursor(); auto cursor = input_->textCursor();
cursor.movePosition(QTextCursor::End); cursor.movePosition(QTextCursor::End);
input_->setTextCursor(cursor); input_->setTextCursor(cursor);
input_->setRelatedEvent(replied_event);
} }

View file

@ -54,6 +54,7 @@ public:
QSize minimumSizeHint() const override; QSize minimumSizeHint() const override;
void submit(); void submit();
void setRelatedEvent(const QString &event) { related_event_ = event; }
signals: signals:
void heightChanged(int height); void heightChanged(int height);
@ -61,6 +62,7 @@ signals:
void stoppedTyping(); void stoppedTyping();
void startedUpload(); void startedUpload();
void message(QString); void message(QString);
void reply(QString, QString);
void command(QString name, QString args); void command(QString name, QString args);
void image(QSharedPointer<QIODevice> data, const QString &filename); void image(QSharedPointer<QIODevice> data, const QString &filename);
void audio(QSharedPointer<QIODevice> data, const QString &filename); void audio(QSharedPointer<QIODevice> data, const QString &filename);
@ -94,6 +96,9 @@ private:
SuggestionsPopup popup_; SuggestionsPopup popup_;
// Used for replies
QString related_event_;
enum class AnchorType enum class AnchorType
{ {
Tab = 0, Tab = 0,
@ -158,13 +163,14 @@ public slots:
void openFileSelection(); void openFileSelection();
void hideUploadSpinner(); void hideUploadSpinner();
void focusLineEdit() { input_->setFocus(); } void focusLineEdit() { input_->setFocus(); }
void addReply(const QString &username, const QString &msg); void addReply(const QString &username, const QString &msg, const QString &related_event);
private slots: private slots:
void addSelectedEmoji(const QString &emoji); void addSelectedEmoji(const QString &emoji);
signals: signals:
void sendTextMessage(QString msg); void sendTextMessage(QString msg);
void sendReplyMessage(QString msg, QString event_id);
void sendEmoteMessage(QString msg); void sendEmoteMessage(QString msg);
void heightChanged(int height); void heightChanged(int height);
@ -189,6 +195,9 @@ private:
QHBoxLayout *topLayout_; QHBoxLayout *topLayout_;
FilteredTextEdit *input_; FilteredTextEdit *input_;
// Used for replies
QString related_event_;
LoadingIndicator *spinner_; LoadingIndicator *spinner_;
FlatButton *sendFileBtn_; FlatButton *sendFileBtn_;

View file

@ -875,7 +875,7 @@ TimelineItem::replyAction()
return; return;
emit ChatPage::instance()->messageReply( emit ChatPage::instance()->messageReply(
Cache::displayName(room_id_, descriptionMsg_.userid), body_->toPlainText()); Cache::displayName(room_id_, descriptionMsg_.userid), body_->toPlainText(), eventId());
} }
void void

View file

@ -690,7 +690,7 @@ TimelineView::updatePendingMessage(const std::string &txn_id, const QString &eve
} }
void void
TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body) TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body, const QString &related_event)
{ {
auto with_sender = (lastSender_ != local_user_) || isDateDifference(lastMsgTimestamp_); auto with_sender = (lastSender_ != local_user_) || isDateDifference(lastMsgTimestamp_);
@ -702,6 +702,9 @@ TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body)
message.txn_id = http::client()->generate_txn_id(); message.txn_id = http::client()->generate_txn_id();
message.body = body; message.body = body;
message.widget = view_item; message.widget = view_item;
if (!related_event.isEmpty()) {
message.related_event = related_event.toStdString();
}
try { try {
message.is_encrypted = cache::client()->isRoomEncrypted(room_id_.toStdString()); message.is_encrypted = cache::client()->isRoomEncrypted(room_id_.toStdString());
@ -722,6 +725,12 @@ TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body)
handleNewUserMessage(message); handleNewUserMessage(message);
} }
void
TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body)
{
addUserMessage(ty, body, "");
}
void void
TimelineView::handleNewUserMessage(PendingMessage msg) TimelineView::handleNewUserMessage(PendingMessage msg)
{ {
@ -1267,6 +1276,10 @@ toRoomMessage<mtx::events::msg::Text>(const PendingMessage &m)
if (html != m.body.trimmed().toHtmlEscaped()) if (html != m.body.trimmed().toHtmlEscaped())
text.formatted_body = html.toStdString(); text.formatted_body = html.toStdString();
if (!m.related_event.empty()) {
text.relates_to.in_reply_to.event_id = m.related_event;
}
return text; return text;
} }

View file

@ -63,6 +63,7 @@ struct PendingMessage
{ {
mtx::events::MessageType ty; mtx::events::MessageType ty;
std::string txn_id; std::string txn_id;
std::string related_event;
QString body; QString body;
QString filename; QString filename;
QString mime; QString mime;
@ -120,6 +121,7 @@ public:
// Add new events at the end of the timeline. // Add new events at the end of the timeline.
void addEvents(const mtx::responses::Timeline &timeline); void addEvents(const mtx::responses::Timeline &timeline);
void addUserMessage(mtx::events::MessageType ty, const QString &body, const QString &related_event);
void addUserMessage(mtx::events::MessageType ty, const QString &msg); void addUserMessage(mtx::events::MessageType ty, const QString &msg);
template<class Widget, mtx::events::MessageType MsgType> template<class Widget, mtx::events::MessageType MsgType>

View file

@ -78,6 +78,19 @@ TimelineViewManager::queueEmoteMessage(const QString &msg)
view->addUserMessage(mtx::events::MessageType::Emote, msg); view->addUserMessage(mtx::events::MessageType::Emote, msg);
} }
void
TimelineViewManager::queueReplyMessage(const QString &reply,
const QString &related_event)
{
if (active_room_.isEmpty())
return;
auto room_id = active_room_;
auto view = views_[room_id];
view->addUserMessage(mtx::events::MessageType::Text, reply, related_event);
}
void void
TimelineViewManager::queueImageMessage(const QString &roomid, TimelineViewManager::queueImageMessage(const QString &roomid,
const QString &filename, const QString &filename,

View file

@ -63,6 +63,8 @@ public slots:
void setHistoryView(const QString &room_id); void setHistoryView(const QString &room_id);
void queueTextMessage(const QString &msg); void queueTextMessage(const QString &msg);
void queueReplyMessage(const QString &reply,
const QString &related_event);
void queueEmoteMessage(const QString &msg); void queueEmoteMessage(const QString &msg);
void queueImageMessage(const QString &roomid, void queueImageMessage(const QString &roomid,
const QString &filename, const QString &filename,