mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-10-30 09:30:47 +03:00
parent
82ec022f9c
commit
dcddea6fb8
14 changed files with 133 additions and 334 deletions
|
@ -303,7 +303,6 @@ set(SRC_FILES
|
||||||
src/Utils.cpp
|
src/Utils.cpp
|
||||||
src/WelcomePage.cpp
|
src/WelcomePage.cpp
|
||||||
src/popups/PopupItem.cpp
|
src/popups/PopupItem.cpp
|
||||||
src/popups/ReplyPopup.cpp
|
|
||||||
src/popups/SuggestionsPopup.cpp
|
src/popups/SuggestionsPopup.cpp
|
||||||
src/popups/UserMentions.cpp
|
src/popups/UserMentions.cpp
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
|
@ -501,7 +500,6 @@ qt5_wrap_cpp(MOC_HEADERS
|
||||||
src/UserSettingsPage.h
|
src/UserSettingsPage.h
|
||||||
src/WelcomePage.h
|
src/WelcomePage.h
|
||||||
src/popups/PopupItem.h
|
src/popups/PopupItem.h
|
||||||
src/popups/ReplyPopup.h
|
|
||||||
src/popups/SuggestionsPopup.h
|
src/popups/SuggestionsPopup.h
|
||||||
src/popups/UserMentions.h
|
src/popups/UserMentions.h
|
||||||
)
|
)
|
||||||
|
|
|
@ -285,7 +285,7 @@ Page {
|
||||||
|
|
||||||
id: replyPopup
|
id: replyPopup
|
||||||
|
|
||||||
visible: timelineManager.replyingEvent && chat.model
|
visible: chat.model && chat.model.reply
|
||||||
// Height of child, plus margins, plus border
|
// Height of child, plus margins, plus border
|
||||||
height: replyPreview.height + 10
|
height: replyPreview.height + 10
|
||||||
color: colors.base
|
color: colors.base
|
||||||
|
@ -300,7 +300,7 @@ Page {
|
||||||
anchors.rightMargin: 20
|
anchors.rightMargin: 20
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
modelData: chat.model ? chat.model.getDump(timelineManager.replyingEvent) : {}
|
modelData: chat.model ? chat.model.getDump(chat.model.reply) : {}
|
||||||
userColor: timelineManager.userColor(modelData.userId, colors.window)
|
userColor: timelineManager.userColor(modelData.userId, colors.window)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +318,7 @@ Page {
|
||||||
ToolTip.visible: closeReplyButton.hovered
|
ToolTip.visible: closeReplyButton.hovered
|
||||||
ToolTip.text: qsTr("Close")
|
ToolTip.text: qsTr("Close")
|
||||||
|
|
||||||
onClicked: timelineManager.closeReply()
|
onClicked: chat.model.reply = undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -303,10 +303,7 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
|
||||||
text_input_,
|
text_input_,
|
||||||
&TextInputWidget::uploadMedia,
|
&TextInputWidget::uploadMedia,
|
||||||
this,
|
this,
|
||||||
[this](QSharedPointer<QIODevice> dev,
|
[this](QSharedPointer<QIODevice> dev, QString mimeClass, const QString &fn) {
|
||||||
QString mimeClass,
|
|
||||||
const QString &fn,
|
|
||||||
const std::optional<RelatedInfo> &related) {
|
|
||||||
if (!dev->open(QIODevice::ReadOnly)) {
|
if (!dev->open(QIODevice::ReadOnly)) {
|
||||||
emit uploadFailed(
|
emit uploadFailed(
|
||||||
QString("Error while reading media: %1").arg(dev->errorString()));
|
QString("Error while reading media: %1").arg(dev->errorString()));
|
||||||
|
@ -358,8 +355,7 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
|
||||||
mime = mime.name(),
|
mime = mime.name(),
|
||||||
size = payload.size(),
|
size = payload.size(),
|
||||||
dimensions,
|
dimensions,
|
||||||
blurhash,
|
blurhash](const mtx::responses::ContentURI &res, mtx::http::RequestErr err) {
|
||||||
related](const mtx::responses::ContentURI &res, mtx::http::RequestErr err) {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
emit uploadFailed(
|
emit uploadFailed(
|
||||||
tr("Failed to upload media. Please try again."));
|
tr("Failed to upload media. Please try again."));
|
||||||
|
@ -378,8 +374,7 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
|
||||||
mime,
|
mime,
|
||||||
size,
|
size,
|
||||||
dimensions,
|
dimensions,
|
||||||
blurhash,
|
blurhash);
|
||||||
related);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -398,8 +393,7 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
|
||||||
QString mime,
|
QString mime,
|
||||||
qint64 dsize,
|
qint64 dsize,
|
||||||
QSize dimensions,
|
QSize dimensions,
|
||||||
QString blurhash,
|
QString blurhash) {
|
||||||
const std::optional<RelatedInfo> &related) {
|
|
||||||
text_input_->hideUploadSpinner();
|
text_input_->hideUploadSpinner();
|
||||||
|
|
||||||
if (encryptedFile)
|
if (encryptedFile)
|
||||||
|
@ -413,17 +407,16 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
|
||||||
mime,
|
mime,
|
||||||
dsize,
|
dsize,
|
||||||
dimensions,
|
dimensions,
|
||||||
blurhash,
|
blurhash);
|
||||||
related);
|
|
||||||
else if (mimeClass == "audio")
|
else if (mimeClass == "audio")
|
||||||
view_manager_->queueAudioMessage(
|
view_manager_->queueAudioMessage(
|
||||||
roomid, filename, encryptedFile, url, mime, dsize, related);
|
roomid, filename, encryptedFile, url, mime, dsize);
|
||||||
else if (mimeClass == "video")
|
else if (mimeClass == "video")
|
||||||
view_manager_->queueVideoMessage(
|
view_manager_->queueVideoMessage(
|
||||||
roomid, filename, encryptedFile, url, mime, dsize, related);
|
roomid, filename, encryptedFile, url, mime, dsize);
|
||||||
else
|
else
|
||||||
view_manager_->queueFileMessage(
|
view_manager_->queueFileMessage(
|
||||||
roomid, filename, encryptedFile, url, mime, dsize, related);
|
roomid, filename, encryptedFile, url, mime, dsize);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(room_list_, &RoomList::roomAvatarChanged, this, &ChatPage::updateTopBarAvatar);
|
connect(room_list_, &RoomList::roomAvatarChanged, this, &ChatPage::updateTopBarAvatar);
|
||||||
|
@ -548,14 +541,6 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(this, &ChatPage::dropToLoginPageCb, this, &ChatPage::dropToLoginPage);
|
connect(this, &ChatPage::dropToLoginPageCb, this, &ChatPage::dropToLoginPage);
|
||||||
connect(this, &ChatPage::messageReply, text_input_, &TextInputWidget::addReply);
|
|
||||||
connect(this, &ChatPage::messageReply, this, [this](const RelatedInfo &related) {
|
|
||||||
view_manager_->updateReplyingEvent(QString::fromStdString(related.related_event));
|
|
||||||
});
|
|
||||||
connect(view_manager_,
|
|
||||||
&TimelineViewManager::replyClosed,
|
|
||||||
text_input_,
|
|
||||||
&TextInputWidget::closeReplyPopup);
|
|
||||||
|
|
||||||
instance_ = this;
|
instance_ = this;
|
||||||
}
|
}
|
||||||
|
@ -596,6 +581,12 @@ ChatPage::resetUI()
|
||||||
showUnreadMessageNotification(0);
|
showUnreadMessageNotification(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ChatPage::focusMessageInput()
|
||||||
|
{
|
||||||
|
this->text_input_->focusLineEdit();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ChatPage::deleteConfigs()
|
ChatPage::deleteConfigs()
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,6 +85,7 @@ public:
|
||||||
//! Show the room/group list (if it was visible).
|
//! Show the room/group list (if it was visible).
|
||||||
void showSideBars();
|
void showSideBars();
|
||||||
void initiateLogout();
|
void initiateLogout();
|
||||||
|
void focusMessageInput();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void leaveRoom(const QString &room_id);
|
void leaveRoom(const QString &room_id);
|
||||||
|
@ -99,8 +100,6 @@ signals:
|
||||||
void connectionLost();
|
void connectionLost();
|
||||||
void connectionRestored();
|
void connectionRestored();
|
||||||
|
|
||||||
void messageReply(const RelatedInfo &related);
|
|
||||||
|
|
||||||
void notificationsRetrieved(const mtx::responses::Notifications &);
|
void notificationsRetrieved(const mtx::responses::Notifications &);
|
||||||
void highlightedNotifsRetrieved(const mtx::responses::Notifications &,
|
void highlightedNotifsRetrieved(const mtx::responses::Notifications &,
|
||||||
const QPoint widgetPos);
|
const QPoint widgetPos);
|
||||||
|
@ -114,8 +113,7 @@ signals:
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
qint64 dsize,
|
qint64 dsize,
|
||||||
const QSize &dimensions,
|
const QSize &dimensions,
|
||||||
const QString &blurhash,
|
const QString &blurhash);
|
||||||
const std::optional<RelatedInfo> &related);
|
|
||||||
|
|
||||||
void contentLoaded();
|
void contentLoaded();
|
||||||
void closing();
|
void closing();
|
||||||
|
|
|
@ -46,7 +46,6 @@ FilteredTextEdit::FilteredTextEdit(QWidget *parent)
|
||||||
: QTextEdit{parent}
|
: QTextEdit{parent}
|
||||||
, history_index_{0}
|
, history_index_{0}
|
||||||
, suggestionsPopup_{parent}
|
, suggestionsPopup_{parent}
|
||||||
, replyPopup_{parent}
|
|
||||||
, previewDialog_{parent}
|
, previewDialog_{parent}
|
||||||
{
|
{
|
||||||
setFrameStyle(QFrame::NoFrame);
|
setFrameStyle(QFrame::NoFrame);
|
||||||
|
@ -73,10 +72,6 @@ FilteredTextEdit::FilteredTextEdit(QWidget *parent)
|
||||||
&FilteredTextEdit::uploadData);
|
&FilteredTextEdit::uploadData);
|
||||||
|
|
||||||
connect(this, &FilteredTextEdit::resultsRetrieved, this, &FilteredTextEdit::showResults);
|
connect(this, &FilteredTextEdit::resultsRetrieved, this, &FilteredTextEdit::showResults);
|
||||||
connect(&replyPopup_, &ReplyPopup::userSelected, this, [](const QString &text) {
|
|
||||||
// TODO: Show user avatar window.
|
|
||||||
nhlog::ui()->info("User selected: " + text.toStdString());
|
|
||||||
});
|
|
||||||
connect(
|
connect(
|
||||||
&suggestionsPopup_, &SuggestionsPopup::itemSelected, this, [this](const QString &text) {
|
&suggestionsPopup_, &SuggestionsPopup::itemSelected, this, [this](const QString &text) {
|
||||||
suggestionsPopup_.hide();
|
suggestionsPopup_.hide();
|
||||||
|
@ -90,8 +85,6 @@ FilteredTextEdit::FilteredTextEdit(QWidget *parent)
|
||||||
cursor.insertText(text);
|
cursor.insertText(text);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(&replyPopup_, &ReplyPopup::cancel, this, [this]() { closeReply(); });
|
|
||||||
|
|
||||||
// For cycling through the suggestions by hitting tab.
|
// For cycling through the suggestions by hitting tab.
|
||||||
connect(this,
|
connect(this,
|
||||||
&FilteredTextEdit::selectNextSuggestion,
|
&FilteredTextEdit::selectNextSuggestion,
|
||||||
|
@ -174,17 +167,6 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replyPopup_.isVisible()) {
|
|
||||||
switch (event->key()) {
|
|
||||||
case Qt::Key_Escape:
|
|
||||||
closeReply();
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event->key()) {
|
switch (event->key()) {
|
||||||
case Qt::Key_At:
|
case Qt::Key_At:
|
||||||
atTriggerPosition_ = textCursor().position();
|
atTriggerPosition_ = textCursor().position();
|
||||||
|
@ -218,7 +200,6 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event)
|
||||||
if (!(event->modifiers() & Qt::ShiftModifier)) {
|
if (!(event->modifiers() & Qt::ShiftModifier)) {
|
||||||
stopTyping();
|
stopTyping();
|
||||||
submit();
|
submit();
|
||||||
closeReply();
|
|
||||||
} else {
|
} else {
|
||||||
QTextEdit::keyPressEvent(event);
|
QTextEdit::keyPressEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -416,30 +397,17 @@ 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, related);
|
message(args);
|
||||||
} else {
|
} else {
|
||||||
command(name, args);
|
command(name, args);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
message(std::move(text), std::move(related));
|
message(std::move(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
related = {};
|
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
FilteredTextEdit::showReplyPopup(const RelatedInfo &related_)
|
|
||||||
{
|
|
||||||
QPoint pos = viewport()->mapToGlobal(this->pos());
|
|
||||||
|
|
||||||
replyPopup_.setReplyContent(related_);
|
|
||||||
replyPopup_.move(pos.x(), pos.y() - replyPopup_.height() - 10);
|
|
||||||
replyPopup_.setFixedWidth(this->parentWidget()->width());
|
|
||||||
replyPopup_.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FilteredTextEdit::textChanged()
|
FilteredTextEdit::textChanged()
|
||||||
{
|
{
|
||||||
|
@ -456,9 +424,7 @@ FilteredTextEdit::uploadData(const QByteArray data,
|
||||||
|
|
||||||
emit startedUpload();
|
emit startedUpload();
|
||||||
|
|
||||||
emit media(buffer, mediaType, filename, related);
|
emit media(buffer, mediaType, filename);
|
||||||
related = {};
|
|
||||||
closeReply();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -599,7 +565,7 @@ void
|
||||||
TextInputWidget::command(QString command, QString args)
|
TextInputWidget::command(QString command, QString args)
|
||||||
{
|
{
|
||||||
if (command == "me") {
|
if (command == "me") {
|
||||||
sendEmoteMessage(args, input_->related);
|
sendEmoteMessage(args);
|
||||||
} else if (command == "join") {
|
} else if (command == "join") {
|
||||||
sendJoinRoomRequest(args);
|
sendJoinRoomRequest(args);
|
||||||
} else if (command == "invite") {
|
} else if (command == "invite") {
|
||||||
|
@ -611,16 +577,14 @@ TextInputWidget::command(QString command, QString args)
|
||||||
} else if (command == "unban") {
|
} else if (command == "unban") {
|
||||||
sendUnbanRoomRequest(args.section(' ', 0, 0), args.section(' ', 1, -1));
|
sendUnbanRoomRequest(args.section(' ', 0, 0), args.section(' ', 1, -1));
|
||||||
} else if (command == "shrug") {
|
} else if (command == "shrug") {
|
||||||
sendTextMessage("¯\\_(ツ)_/¯", input_->related);
|
sendTextMessage("¯\\_(ツ)_/¯");
|
||||||
} else if (command == "fliptable") {
|
} else if (command == "fliptable") {
|
||||||
sendTextMessage("(╯°□°)╯︵ ┻━┻", input_->related);
|
sendTextMessage("(╯°□°)╯︵ ┻━┻");
|
||||||
} else if (command == "unfliptable") {
|
} else if (command == "unfliptable") {
|
||||||
sendTextMessage(" ┯━┯╭( º _ º╭)", input_->related);
|
sendTextMessage(" ┯━┯╭( º _ º╭)");
|
||||||
} else if (command == "sovietflip") {
|
} else if (command == "sovietflip") {
|
||||||
sendTextMessage("ノ┬─┬ノ ︵ ( \\o°o)\\", input_->related);
|
sendTextMessage("ノ┬─┬ノ ︵ ( \\o°o)\\");
|
||||||
}
|
}
|
||||||
|
|
||||||
input_->related = std::nullopt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -640,9 +604,7 @@ TextInputWidget::openFileSelection()
|
||||||
|
|
||||||
QSharedPointer<QFile> file{new QFile{fileName, this}};
|
QSharedPointer<QFile> file{new QFile{fileName, this}};
|
||||||
|
|
||||||
emit uploadMedia(file, format, QFileInfo(fileName).fileName(), input_->related);
|
emit uploadMedia(file, format, QFileInfo(fileName).fileName());
|
||||||
input_->related = {};
|
|
||||||
input_->closeReply();
|
|
||||||
|
|
||||||
showUploadSpinner();
|
showUploadSpinner();
|
||||||
}
|
}
|
||||||
|
@ -687,16 +649,3 @@ TextInputWidget::paintEvent(QPaintEvent *)
|
||||||
|
|
||||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
TextInputWidget::addReply(const RelatedInfo &related)
|
|
||||||
{
|
|
||||||
// input_->setText(QString("> %1: %2\n\n").arg(username).arg(msg));
|
|
||||||
input_->setFocus();
|
|
||||||
|
|
||||||
// input_->showReplyPopup(related);
|
|
||||||
auto cursor = input_->textCursor();
|
|
||||||
cursor.movePosition(QTextCursor::End);
|
|
||||||
input_->setTextCursor(cursor);
|
|
||||||
input_->related = related;
|
|
||||||
}
|
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
#include "dialogs/PreviewUploadOverlay.h"
|
#include "dialogs/PreviewUploadOverlay.h"
|
||||||
#include "emoji/PickButton.h"
|
#include "emoji/PickButton.h"
|
||||||
#include "popups/ReplyPopup.h"
|
|
||||||
#include "popups/SuggestionsPopup.h"
|
#include "popups/SuggestionsPopup.h"
|
||||||
|
|
||||||
struct SearchResult;
|
struct SearchResult;
|
||||||
|
@ -49,27 +48,15 @@ public:
|
||||||
QSize minimumSizeHint() const override;
|
QSize minimumSizeHint() const override;
|
||||||
|
|
||||||
void submit();
|
void submit();
|
||||||
void showReplyPopup(const RelatedInfo &related_);
|
|
||||||
void closeReply()
|
|
||||||
{
|
|
||||||
replyPopup_.hide();
|
|
||||||
related = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used for replies
|
|
||||||
std::optional<RelatedInfo> related;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void heightChanged(int height);
|
void heightChanged(int height);
|
||||||
void startedTyping();
|
void startedTyping();
|
||||||
void stoppedTyping();
|
void stoppedTyping();
|
||||||
void startedUpload();
|
void startedUpload();
|
||||||
void message(QString, const std::optional<RelatedInfo> &);
|
void message(QString msg);
|
||||||
void command(QString name, QString args);
|
void command(QString name, QString args);
|
||||||
void media(QSharedPointer<QIODevice> data,
|
void media(QSharedPointer<QIODevice> data, QString mimeClass, const QString &filename);
|
||||||
QString mimeClass,
|
|
||||||
const QString &filename,
|
|
||||||
const std::optional<RelatedInfo> &related);
|
|
||||||
|
|
||||||
//! Trigger the suggestion popup.
|
//! Trigger the suggestion popup.
|
||||||
void showSuggestions(const QString &query);
|
void showSuggestions(const QString &query);
|
||||||
|
@ -97,7 +84,6 @@ private:
|
||||||
QTimer *typingTimer_;
|
QTimer *typingTimer_;
|
||||||
|
|
||||||
SuggestionsPopup suggestionsPopup_;
|
SuggestionsPopup suggestionsPopup_;
|
||||||
ReplyPopup replyPopup_;
|
|
||||||
|
|
||||||
enum class AnchorType
|
enum class AnchorType
|
||||||
{
|
{
|
||||||
|
@ -163,21 +149,18 @@ public slots:
|
||||||
void openFileSelection();
|
void openFileSelection();
|
||||||
void hideUploadSpinner();
|
void hideUploadSpinner();
|
||||||
void focusLineEdit() { input_->setFocus(); }
|
void focusLineEdit() { input_->setFocus(); }
|
||||||
void addReply(const RelatedInfo &related);
|
|
||||||
void closeReplyPopup() { input_->closeReply(); }
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void addSelectedEmoji(const QString &emoji);
|
void addSelectedEmoji(const QString &emoji);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sendTextMessage(const QString &msg, const std::optional<RelatedInfo> &related);
|
void sendTextMessage(const QString &msg);
|
||||||
void sendEmoteMessage(QString msg, const std::optional<RelatedInfo> &related);
|
void sendEmoteMessage(QString msg);
|
||||||
void heightChanged(int height);
|
void heightChanged(int height);
|
||||||
|
|
||||||
void uploadMedia(const QSharedPointer<QIODevice> data,
|
void uploadMedia(const QSharedPointer<QIODevice> data,
|
||||||
QString mimeClass,
|
QString mimeClass,
|
||||||
const QString &filename,
|
const QString &filename);
|
||||||
const std::optional<RelatedInfo> &related);
|
|
||||||
|
|
||||||
void sendJoinRoomRequest(const QString &room);
|
void sendJoinRoomRequest(const QString &room);
|
||||||
void sendInviteRoomRequest(const QString &userid, const QString &reason);
|
void sendInviteRoomRequest(const QString &userid, const QString &reason);
|
||||||
|
|
|
@ -97,9 +97,9 @@ NotificationsManager::closeNotification(uint id)
|
||||||
|
|
||||||
void
|
void
|
||||||
NotificationsManager::removeNotification(const QString &roomId, const QString &eventId)
|
NotificationsManager::removeNotification(const QString &roomId, const QString &eventId)
|
||||||
|
{
|
||||||
roomEventId reId = {roomId, eventId};
|
roomEventId reId = {roomId, eventId};
|
||||||
for (auto elem = notificationIds.begin(); elem != notificationIds.end(); ++elem) {
|
for (auto elem = notificationIds.begin(); elem != notificationIds.end(); ++elem) {
|
||||||
if (elem.value().roomId != roomId)
|
if (elem.value().roomId != roomId)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -110,9 +110,9 @@ for (auto elem = notificationIds.begin(); elem != notificationIds.end(); ++elem)
|
||||||
// Otherwise we would need to store a 64bit counter instead.
|
// Otherwise we would need to store a 64bit counter instead.
|
||||||
closeNotification(elem.key());
|
closeNotification(elem.key());
|
||||||
|
|
||||||
// FIXME: compare index of event id of the read receipt and the notification instead of just
|
// FIXME: compare index of event id of the read receipt and the notification instead
|
||||||
// the id to prevent read receipts of events without notification clearing all notifications
|
// of just the id to prevent read receipts of events without notification clearing
|
||||||
// in that room!
|
// all notifications in that room!
|
||||||
if (elem.value() == reId)
|
if (elem.value() == reId)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,4 +67,3 @@ void NotificationsManager::notificationClosed(uint, uint) {}
|
||||||
void
|
void
|
||||||
NotificationsManager::removeNotification(const QString &roomId, const QString &eventId)
|
NotificationsManager::removeNotification(const QString &roomId, const QString &eventId)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -1,103 +0,0 @@
|
||||||
#include <QLabel>
|
|
||||||
#include <QPaintEvent>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QStyleOption>
|
|
||||||
|
|
||||||
#include "../Config.h"
|
|
||||||
#include "../Utils.h"
|
|
||||||
#include "../ui/Avatar.h"
|
|
||||||
#include "../ui/DropShadow.h"
|
|
||||||
#include "../ui/TextLabel.h"
|
|
||||||
#include "PopupItem.h"
|
|
||||||
#include "ReplyPopup.h"
|
|
||||||
|
|
||||||
ReplyPopup::ReplyPopup(QWidget *parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
, userItem_{nullptr}
|
|
||||||
, msgLabel_{nullptr}
|
|
||||||
, eventLabel_{nullptr}
|
|
||||||
{
|
|
||||||
setAttribute(Qt::WA_ShowWithoutActivating, true);
|
|
||||||
setWindowFlags(Qt::ToolTip | Qt::NoDropShadowWindowHint);
|
|
||||||
|
|
||||||
mainLayout_ = new QVBoxLayout(this);
|
|
||||||
mainLayout_->setMargin(0);
|
|
||||||
mainLayout_->setSpacing(0);
|
|
||||||
|
|
||||||
topLayout_ = new QHBoxLayout();
|
|
||||||
topLayout_->setSpacing(0);
|
|
||||||
topLayout_->setContentsMargins(13, 1, 13, 0);
|
|
||||||
|
|
||||||
userItem_ = new UserItem(this);
|
|
||||||
connect(userItem_, &UserItem::clicked, this, &ReplyPopup::userSelected);
|
|
||||||
topLayout_->addWidget(userItem_);
|
|
||||||
|
|
||||||
buttonLayout_ = new QHBoxLayout();
|
|
||||||
buttonLayout_->setSpacing(0);
|
|
||||||
buttonLayout_->setMargin(0);
|
|
||||||
|
|
||||||
topLayout_->addLayout(buttonLayout_);
|
|
||||||
QFont f;
|
|
||||||
f.setPointSizeF(f.pointSizeF());
|
|
||||||
const int fontHeight = QFontMetrics(f).height();
|
|
||||||
buttonSize_ = std::min(fontHeight, 20);
|
|
||||||
|
|
||||||
closeBtn_ = new FlatButton(this);
|
|
||||||
closeBtn_->setToolTip(tr("Logout"));
|
|
||||||
closeBtn_->setCornerRadius(buttonSize_ / 4);
|
|
||||||
closeBtn_->setText("X");
|
|
||||||
|
|
||||||
QIcon icon;
|
|
||||||
icon.addFile(":/icons/icons/ui/remove-symbol.png");
|
|
||||||
|
|
||||||
closeBtn_->setIcon(icon);
|
|
||||||
closeBtn_->setIconSize(QSize(buttonSize_, buttonSize_));
|
|
||||||
connect(closeBtn_, &FlatButton::clicked, this, [this]() { emit cancel(); });
|
|
||||||
|
|
||||||
buttonLayout_->addWidget(closeBtn_);
|
|
||||||
|
|
||||||
topLayout_->addLayout(buttonLayout_);
|
|
||||||
|
|
||||||
mainLayout_->addLayout(topLayout_);
|
|
||||||
msgLabel_ = new TextLabel(this);
|
|
||||||
msgLabel_->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextBrowserInteraction);
|
|
||||||
mainLayout_->addWidget(msgLabel_);
|
|
||||||
eventLabel_ = new QLabel(this);
|
|
||||||
mainLayout_->addWidget(eventLabel_);
|
|
||||||
|
|
||||||
setLayout(mainLayout_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ReplyPopup::setReplyContent(const RelatedInfo &related)
|
|
||||||
{
|
|
||||||
// Update the current widget with the new data.
|
|
||||||
userItem_->updateItem(related.quoted_user);
|
|
||||||
|
|
||||||
msgLabel_->setText(utils::getFormattedQuoteBody(related, "")
|
|
||||||
.replace("<mx-reply>", "")
|
|
||||||
.replace("</mx-reply>", ""));
|
|
||||||
|
|
||||||
// eventLabel_->setText(srcEvent);
|
|
||||||
|
|
||||||
adjustSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ReplyPopup::paintEvent(QPaintEvent *)
|
|
||||||
{
|
|
||||||
QStyleOption opt;
|
|
||||||
opt.init(this);
|
|
||||||
QPainter p(this);
|
|
||||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ReplyPopup::mousePressEvent(QMouseEvent *event)
|
|
||||||
{
|
|
||||||
if (event->buttons() != Qt::RightButton) {
|
|
||||||
emit clicked(eventLabel_->text());
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget::mousePressEvent(event);
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
#include "../ui/FlatButton.h"
|
|
||||||
#include "../ui/TextLabel.h"
|
|
||||||
|
|
||||||
struct RelatedInfo;
|
|
||||||
class UserItem;
|
|
||||||
|
|
||||||
class ReplyPopup : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ReplyPopup(QWidget *parent = nullptr);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void setReplyContent(const RelatedInfo &related);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *event) override;
|
|
||||||
void mousePressEvent(QMouseEvent *event) override;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void userSelected(const QString &user);
|
|
||||||
void clicked(const QString &text);
|
|
||||||
void cancel();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QHBoxLayout *topLayout_;
|
|
||||||
QVBoxLayout *mainLayout_;
|
|
||||||
QHBoxLayout *buttonLayout_;
|
|
||||||
|
|
||||||
UserItem *userItem_;
|
|
||||||
FlatButton *closeBtn_;
|
|
||||||
TextLabel *msgLabel_;
|
|
||||||
QLabel *eventLabel_;
|
|
||||||
|
|
||||||
int buttonSize_;
|
|
||||||
};
|
|
|
@ -800,6 +800,16 @@ TimelineModel::decryptEvent(const mtx::events::EncryptedEvent<mtx::events::msg::
|
||||||
void
|
void
|
||||||
TimelineModel::replyAction(QString id)
|
TimelineModel::replyAction(QString id)
|
||||||
{
|
{
|
||||||
|
setReply(id);
|
||||||
|
ChatPage::instance()->focusMessageInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
RelatedInfo
|
||||||
|
TimelineModel::relatedInfo(QString id)
|
||||||
|
{
|
||||||
|
if (!events.contains(id))
|
||||||
|
return {};
|
||||||
|
|
||||||
auto event = events.value(id);
|
auto event = events.value(id);
|
||||||
if (auto e =
|
if (auto e =
|
||||||
std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(&event)) {
|
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 = mtx::accessors::formattedBodyWithFallback(event);
|
||||||
related.quoted_formatted_body.remove(QRegularExpression(
|
related.quoted_formatted_body.remove(QRegularExpression(
|
||||||
"<mx-reply>.*</mx-reply>", QRegularExpression::DotMatchesEverythingOption));
|
"<mx-reply>.*</mx-reply>", QRegularExpression::DotMatchesEverythingOption));
|
||||||
nhlog::ui()->debug("after replacement: {}", related.quoted_body.toStdString());
|
|
||||||
related.room = room_id_;
|
related.room = room_id_;
|
||||||
|
|
||||||
ChatPage::instance()->messageReply(related);
|
return related;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -18,6 +18,7 @@ struct Timeline;
|
||||||
struct Messages;
|
struct Messages;
|
||||||
struct ClaimKeys;
|
struct ClaimKeys;
|
||||||
}
|
}
|
||||||
|
struct RelatedInfo;
|
||||||
|
|
||||||
namespace qml_mtx_events {
|
namespace qml_mtx_events {
|
||||||
Q_NAMESPACE
|
Q_NAMESPACE
|
||||||
|
@ -124,6 +125,7 @@ class TimelineModel : public QAbstractListModel
|
||||||
int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
|
int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
|
||||||
Q_PROPERTY(std::vector<QString> typingUsers READ typingUsers WRITE updateTypingUsers NOTIFY
|
Q_PROPERTY(std::vector<QString> typingUsers READ typingUsers WRITE updateTypingUsers NOTIFY
|
||||||
typingUsersChanged)
|
typingUsersChanged)
|
||||||
|
Q_PROPERTY(QString reply READ reply WRITE setReply NOTIFY replyChanged RESET resetReply)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TimelineModel(TimelineViewManager *manager,
|
explicit TimelineModel(TimelineViewManager *manager,
|
||||||
|
@ -191,6 +193,7 @@ public:
|
||||||
void addEvents(const mtx::responses::Timeline &events);
|
void addEvents(const mtx::responses::Timeline &events);
|
||||||
template<class T>
|
template<class T>
|
||||||
void sendMessage(const T &msg);
|
void sendMessage(const T &msg);
|
||||||
|
RelatedInfo relatedInfo(QString id);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setCurrentIndex(int index);
|
void setCurrentIndex(int index);
|
||||||
|
@ -206,6 +209,22 @@ public slots:
|
||||||
}
|
}
|
||||||
std::vector<QString> typingUsers() const { return typingUsers_; }
|
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:
|
private slots:
|
||||||
// Add old events at the top of the timeline.
|
// Add old events at the top of the timeline.
|
||||||
void addBackwardsEvents(const mtx::responses::Messages &msgs);
|
void addBackwardsEvents(const mtx::responses::Messages &msgs);
|
||||||
|
@ -225,6 +244,7 @@ signals:
|
||||||
void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo);
|
void newEncryptedImage(mtx::crypto::EncryptedFile encryptionInfo);
|
||||||
void eventFetched(QString requestingEvent, mtx::events::collections::TimelineEvents event);
|
void eventFetched(QString requestingEvent, mtx::events::collections::TimelineEvents event);
|
||||||
void typingUsersChanged(std::vector<QString> users);
|
void typingUsersChanged(std::vector<QString> users);
|
||||||
|
void replyChanged(QString reply);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DecryptionResult decryptEvent(
|
DecryptionResult decryptEvent(
|
||||||
|
@ -254,6 +274,7 @@ private:
|
||||||
bool isProcessingPending = false;
|
bool isProcessingPending = false;
|
||||||
|
|
||||||
QString currentId;
|
QString currentId;
|
||||||
|
QString reply_;
|
||||||
std::vector<QString> typingUsers_;
|
std::vector<QString> typingUsers_;
|
||||||
|
|
||||||
TimelineViewManager *manager_;
|
TimelineViewManager *manager_;
|
||||||
|
|
|
@ -188,8 +188,11 @@ TimelineViewManager::initWithMessages(const std::map<QString, mtx::responses::Ti
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TimelineViewManager::queueTextMessage(const QString &msg, const std::optional<RelatedInfo> &related)
|
TimelineViewManager::queueTextMessage(const QString &msg)
|
||||||
{
|
{
|
||||||
|
if (!timeline_)
|
||||||
|
return;
|
||||||
|
|
||||||
mtx::events::msg::Text text = {};
|
mtx::events::msg::Text text = {};
|
||||||
text.body = msg.trimmed().toStdString();
|
text.body = msg.trimmed().toStdString();
|
||||||
|
|
||||||
|
@ -203,13 +206,15 @@ TimelineViewManager::queueTextMessage(const QString &msg, const std::optional<Re
|
||||||
text.format = "org.matrix.custom.html";
|
text.format = "org.matrix.custom.html";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (related) {
|
if (!timeline_->reply().isEmpty()) {
|
||||||
|
auto related = timeline_->relatedInfo(timeline_->reply());
|
||||||
|
|
||||||
QString body;
|
QString body;
|
||||||
bool firstLine = true;
|
bool firstLine = true;
|
||||||
for (const auto &line : related->quoted_body.split("\n")) {
|
for (const auto &line : related.quoted_body.split("\n")) {
|
||||||
if (firstLine) {
|
if (firstLine) {
|
||||||
firstLine = false;
|
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 {
|
} else {
|
||||||
body = QString("%1\n> %2\n").arg(body).arg(line);
|
body = QString("%1\n> %2\n").arg(body).arg(line);
|
||||||
}
|
}
|
||||||
|
@ -221,16 +226,16 @@ TimelineViewManager::queueTextMessage(const QString &msg, const std::optional<Re
|
||||||
text.format = "org.matrix.custom.html";
|
text.format = "org.matrix.custom.html";
|
||||||
if (settings->isMarkdownEnabled())
|
if (settings->isMarkdownEnabled())
|
||||||
text.formatted_body =
|
text.formatted_body =
|
||||||
utils::getFormattedQuoteBody(*related, utils::markdownToHtml(msg))
|
utils::getFormattedQuoteBody(related, utils::markdownToHtml(msg))
|
||||||
.toStdString();
|
.toStdString();
|
||||||
else
|
else
|
||||||
text.formatted_body =
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,6 +252,11 @@ TimelineViewManager::queueEmoteMessage(const QString &msg)
|
||||||
emote.format = "org.matrix.custom.html";
|
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_)
|
if (timeline_)
|
||||||
timeline_->sendMessage(emote);
|
timeline_->sendMessage(emote);
|
||||||
}
|
}
|
||||||
|
@ -259,8 +269,7 @@ TimelineViewManager::queueImageMessage(const QString &roomid,
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
uint64_t dsize,
|
uint64_t dsize,
|
||||||
const QSize &dimensions,
|
const QSize &dimensions,
|
||||||
const QString &blurhash,
|
const QString &blurhash)
|
||||||
const std::optional<RelatedInfo> &related)
|
|
||||||
{
|
{
|
||||||
mtx::events::msg::Image image;
|
mtx::events::msg::Image image;
|
||||||
image.info.mimetype = mime.toStdString();
|
image.info.mimetype = mime.toStdString();
|
||||||
|
@ -272,10 +281,13 @@ TimelineViewManager::queueImageMessage(const QString &roomid,
|
||||||
image.info.w = dimensions.width();
|
image.info.w = dimensions.width();
|
||||||
image.file = file;
|
image.file = file;
|
||||||
|
|
||||||
if (related)
|
auto model = models.value(roomid);
|
||||||
image.relates_to.in_reply_to.event_id = related->related_event;
|
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
|
void
|
||||||
|
@ -285,8 +297,7 @@ TimelineViewManager::queueFileMessage(
|
||||||
const std::optional<mtx::crypto::EncryptedFile> &encryptedFile,
|
const std::optional<mtx::crypto::EncryptedFile> &encryptedFile,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
uint64_t dsize,
|
uint64_t dsize)
|
||||||
const std::optional<RelatedInfo> &related)
|
|
||||||
{
|
{
|
||||||
mtx::events::msg::File file;
|
mtx::events::msg::File file;
|
||||||
file.info.mimetype = mime.toStdString();
|
file.info.mimetype = mime.toStdString();
|
||||||
|
@ -295,10 +306,13 @@ TimelineViewManager::queueFileMessage(
|
||||||
file.url = url.toStdString();
|
file.url = url.toStdString();
|
||||||
file.file = encryptedFile;
|
file.file = encryptedFile;
|
||||||
|
|
||||||
if (related)
|
auto model = models.value(roomid);
|
||||||
file.relates_to.in_reply_to.event_id = related->related_event;
|
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
|
void
|
||||||
|
@ -307,8 +321,7 @@ TimelineViewManager::queueAudioMessage(const QString &roomid,
|
||||||
const std::optional<mtx::crypto::EncryptedFile> &file,
|
const std::optional<mtx::crypto::EncryptedFile> &file,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
uint64_t dsize,
|
uint64_t dsize)
|
||||||
const std::optional<RelatedInfo> &related)
|
|
||||||
{
|
{
|
||||||
mtx::events::msg::Audio audio;
|
mtx::events::msg::Audio audio;
|
||||||
audio.info.mimetype = mime.toStdString();
|
audio.info.mimetype = mime.toStdString();
|
||||||
|
@ -317,10 +330,13 @@ TimelineViewManager::queueAudioMessage(const QString &roomid,
|
||||||
audio.url = url.toStdString();
|
audio.url = url.toStdString();
|
||||||
audio.file = file;
|
audio.file = file;
|
||||||
|
|
||||||
if (related)
|
auto model = models.value(roomid);
|
||||||
audio.relates_to.in_reply_to.event_id = related->related_event;
|
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
|
void
|
||||||
|
@ -329,8 +345,7 @@ TimelineViewManager::queueVideoMessage(const QString &roomid,
|
||||||
const std::optional<mtx::crypto::EncryptedFile> &file,
|
const std::optional<mtx::crypto::EncryptedFile> &file,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
uint64_t dsize,
|
uint64_t dsize)
|
||||||
const std::optional<RelatedInfo> &related)
|
|
||||||
{
|
{
|
||||||
mtx::events::msg::Video video;
|
mtx::events::msg::Video video;
|
||||||
video.info.mimetype = mime.toStdString();
|
video.info.mimetype = mime.toStdString();
|
||||||
|
@ -339,8 +354,11 @@ TimelineViewManager::queueVideoMessage(const QString &roomid,
|
||||||
video.url = url.toStdString();
|
video.url = url.toStdString();
|
||||||
video.file = file;
|
video.file = file;
|
||||||
|
|
||||||
if (related)
|
auto model = models.value(roomid);
|
||||||
video.relates_to.in_reply_to.event_id = related->related_event;
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,6 @@ class TimelineViewManager : public QObject
|
||||||
TimelineModel *timeline MEMBER timeline_ READ activeTimeline NOTIFY activeTimelineChanged)
|
TimelineModel *timeline MEMBER timeline_ READ activeTimeline NOTIFY activeTimelineChanged)
|
||||||
Q_PROPERTY(
|
Q_PROPERTY(
|
||||||
bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged)
|
bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged)
|
||||||
Q_PROPERTY(QString replyingEvent READ getReplyingEvent WRITE updateReplyingEvent NOTIFY
|
|
||||||
replyingEventChanged)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TimelineViewManager(QSharedPointer<UserSettings> userSettings, QWidget *parent = nullptr);
|
TimelineViewManager(QSharedPointer<UserSettings> userSettings, QWidget *parent = nullptr);
|
||||||
|
@ -52,26 +50,13 @@ signals:
|
||||||
void replyClosed();
|
void replyClosed();
|
||||||
|
|
||||||
public slots:
|
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 updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
|
||||||
void initWithMessages(const std::map<QString, mtx::responses::Timeline> &msgs);
|
void initWithMessages(const std::map<QString, mtx::responses::Timeline> &msgs);
|
||||||
|
|
||||||
void setHistoryView(const QString &room_id);
|
void setHistoryView(const QString &room_id);
|
||||||
void updateColorPalette();
|
void updateColorPalette();
|
||||||
|
|
||||||
void queueTextMessage(const QString &msg, const std::optional<RelatedInfo> &related);
|
void queueTextMessage(const QString &msg);
|
||||||
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,
|
||||||
|
@ -80,29 +65,25 @@ public slots:
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
uint64_t dsize,
|
uint64_t dsize,
|
||||||
const QSize &dimensions,
|
const QSize &dimensions,
|
||||||
const QString &blurhash,
|
const QString &blurhash);
|
||||||
const std::optional<RelatedInfo> &related);
|
|
||||||
void queueFileMessage(const QString &roomid,
|
void queueFileMessage(const QString &roomid,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
const std::optional<mtx::crypto::EncryptedFile> &file,
|
const std::optional<mtx::crypto::EncryptedFile> &file,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
uint64_t dsize,
|
uint64_t dsize);
|
||||||
const std::optional<RelatedInfo> &related);
|
|
||||||
void queueAudioMessage(const QString &roomid,
|
void queueAudioMessage(const QString &roomid,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
const std::optional<mtx::crypto::EncryptedFile> &file,
|
const std::optional<mtx::crypto::EncryptedFile> &file,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
uint64_t dsize,
|
uint64_t dsize);
|
||||||
const std::optional<RelatedInfo> &related);
|
|
||||||
void queueVideoMessage(const QString &roomid,
|
void queueVideoMessage(const QString &roomid,
|
||||||
const QString &filename,
|
const QString &filename,
|
||||||
const std::optional<mtx::crypto::EncryptedFile> &file,
|
const std::optional<mtx::crypto::EncryptedFile> &file,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
uint64_t dsize,
|
uint64_t dsize);
|
||||||
const std::optional<RelatedInfo> &related);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef USE_QUICK_VIEW
|
#ifdef USE_QUICK_VIEW
|
||||||
|
@ -119,7 +100,6 @@ private:
|
||||||
QHash<QString, QSharedPointer<TimelineModel>> models;
|
QHash<QString, QSharedPointer<TimelineModel>> models;
|
||||||
TimelineModel *timeline_ = nullptr;
|
TimelineModel *timeline_ = nullptr;
|
||||||
bool isInitialSync_ = true;
|
bool isInitialSync_ = true;
|
||||||
QString replyingEvent_;
|
|
||||||
|
|
||||||
QSharedPointer<UserSettings> settings;
|
QSharedPointer<UserSettings> settings;
|
||||||
QHash<QString, QColor> userColors;
|
QHash<QString, QColor> userColors;
|
||||||
|
|
Loading…
Reference in a new issue