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(
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
5cdcd7d6feaefa8df8966bd053ea2d1181eb7e6c0f3b548b2f98f00400e2760e)
b31ec18b9d7d74db1a17b930bfa570fa1cede56cc49b43948b7d86c396f2f3d3)
set(
TWEENY_URL
https://github.com/mobius3/tweeny/archive/b94ce07cfb02a0eb8ac8aaf66137dabdaea857cf.tar.gz

View File

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

View File

@ -83,7 +83,7 @@ signals:
void connectionLost();
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 &);

View File

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

View File

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

View File

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

View File

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

View File

@ -63,6 +63,7 @@ struct PendingMessage
{
mtx::events::MessageType ty;
std::string txn_id;
std::string related_event;
QString body;
QString filename;
QString mime;
@ -120,6 +121,7 @@ public:
// Add new events at the end of the 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);
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);
}
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
TimelineViewManager::queueImageMessage(const QString &roomid,
const QString &filename,

View File

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