Implement message editing

The UI still looks ugly, but I have no good idea atm.

fixes #134
This commit is contained in:
Nicolas Werner 2021-02-01 02:22:53 +01:00
parent 00fd4eecec
commit 9b7d33e847
9 changed files with 90 additions and 15 deletions

View file

@ -356,7 +356,7 @@ if(USE_BUNDLED_MTXCLIENT)
FetchContent_Declare( FetchContent_Declare(
MatrixClient MatrixClient
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
GIT_TAG 31e300546eb63ea25b0b879fb255beee6022da03 GIT_TAG fee5298f068394958c2de935836a2c145f273906
) )
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "") set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "") set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")

View file

@ -220,7 +220,7 @@
"name": "mtxclient", "name": "mtxclient",
"sources": [ "sources": [
{ {
"commit": "31e300546eb63ea25b0b879fb255beee6022da03", "commit": "fee5298f068394958c2de935836a2c145f273906",
"type": "git", "type": "git",
"url": "https://github.com/Nheko-Reborn/mtxclient.git" "url": "https://github.com/Nheko-Reborn/mtxclient.git"
} }

View file

@ -261,6 +261,10 @@ Rectangle {
Connections { Connections {
ignoreUnknownSignals: true ignoreUnknownSignals: true
onInsertText: messageInput.insert(messageInput.cursorPosition, text) onInsertText: messageInput.insert(messageInput.cursorPosition, text)
onTextChanged: {
messageInput.text = newText;
messageInput.cursorPosition = newText.length;
}
target: TimelineManager.timeline ? TimelineManager.timeline.input : null target: TimelineManager.timeline ? TimelineManager.timeline.input : null
} }

View file

@ -10,14 +10,15 @@ Rectangle {
property var room: TimelineManager.timeline property var room: TimelineManager.timeline
Layout.fillWidth: true Layout.fillWidth: true
visible: room && room.reply visible: room && (room.reply || room.edit)
// Height of child, plus margins, plus border // Height of child, plus margins, plus border
implicitHeight: replyPreview.height + 10 implicitHeight: (room && room.reply ? replyPreview.height : closeEditButton.height) + 10
color: colors.window color: colors.window
z: 3 z: 3
Reply { Reply {
id: replyPreview id: replyPreview
visible: room && room.reply
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 2 * 22 + 3 * 16 anchors.leftMargin: 2 * 22 + 3 * 16
@ -31,9 +32,10 @@ Rectangle {
ImageButton { ImageButton {
id: closeReplyButton id: closeReplyButton
visible: room && room.reply
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 15 anchors.rightMargin: 16
anchors.top: replyPreview.top anchors.top: replyPreview.top
hoverEnabled: true hoverEnabled: true
width: 16 width: 16
@ -44,4 +46,17 @@ Rectangle {
onClicked: room.reply = undefined onClicked: room.reply = undefined
} }
Button {
id: closeEditButton
visible: room && room.edit
anchors.left: parent.left
anchors.rightMargin: 16
anchors.topMargin: 10
anchors.top: parent.top
//height: 16
text: qsTr("Abort edit")
onClicked: room.edit = undefined
}
} }

View file

@ -89,6 +89,7 @@ Item {
id: editButton id: editButton
visible: (Settings.buttonsInTimeline && model.isEditable) || model.isEdited visible: (Settings.buttonsInTimeline && model.isEditable) || model.isEdited
buttonTextColor: chat.model.edit == model.id ? colors.highlight : colors.buttonText
Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.alignment: Qt.AlignRight | Qt.AlignTop
Layout.preferredHeight: 16 Layout.preferredHeight: 16
width: 16 width: 16

View file

@ -268,7 +268,18 @@ InputBar::message(QString msg, MarkdownOverride useMarkdown)
text.format = "org.matrix.custom.html"; text.format = "org.matrix.custom.html";
} }
if (!room->reply().isEmpty()) { if (!room->edit().isEmpty()) {
if (!room->reply().isEmpty()) {
text.relations.relations.push_back(
{mtx::common::RelationType::InReplyTo, room->reply().toStdString()});
room->resetReply();
}
text.relations.relations.push_back(
{mtx::common::RelationType::Replace, room->edit().toStdString()});
room->resetEdit();
} else if (!room->reply().isEmpty()) {
auto related = room->relatedInfo(room->reply()); auto related = room->relatedInfo(room->reply());
QString body; QString body;
@ -321,6 +332,11 @@ InputBar::emote(QString msg)
{mtx::common::RelationType::InReplyTo, room->reply().toStdString()}); {mtx::common::RelationType::InReplyTo, room->reply().toStdString()});
room->resetReply(); room->resetReply();
} }
if (!room->edit().isEmpty()) {
emote.relations.relations.push_back(
{mtx::common::RelationType::Replace, room->edit().toStdString()});
room->resetEdit();
}
room->sendMessageEvent(emote, mtx::events::EventType::RoomMessage); room->sendMessageEvent(emote, mtx::events::EventType::RoomMessage);
} }
@ -352,6 +368,11 @@ InputBar::image(const QString &filename,
{mtx::common::RelationType::InReplyTo, room->reply().toStdString()}); {mtx::common::RelationType::InReplyTo, room->reply().toStdString()});
room->resetReply(); room->resetReply();
} }
if (!room->edit().isEmpty()) {
image.relations.relations.push_back(
{mtx::common::RelationType::Replace, room->edit().toStdString()});
room->resetEdit();
}
room->sendMessageEvent(image, mtx::events::EventType::RoomMessage); room->sendMessageEvent(image, mtx::events::EventType::RoomMessage);
} }
@ -378,6 +399,11 @@ InputBar::file(const QString &filename,
{mtx::common::RelationType::InReplyTo, room->reply().toStdString()}); {mtx::common::RelationType::InReplyTo, room->reply().toStdString()});
room->resetReply(); room->resetReply();
} }
if (!room->edit().isEmpty()) {
file.relations.relations.push_back(
{mtx::common::RelationType::Replace, room->edit().toStdString()});
room->resetEdit();
}
room->sendMessageEvent(file, mtx::events::EventType::RoomMessage); room->sendMessageEvent(file, mtx::events::EventType::RoomMessage);
} }
@ -405,6 +431,11 @@ InputBar::audio(const QString &filename,
{mtx::common::RelationType::InReplyTo, room->reply().toStdString()}); {mtx::common::RelationType::InReplyTo, room->reply().toStdString()});
room->resetReply(); room->resetReply();
} }
if (!room->edit().isEmpty()) {
audio.relations.relations.push_back(
{mtx::common::RelationType::Replace, room->edit().toStdString()});
room->resetEdit();
}
room->sendMessageEvent(audio, mtx::events::EventType::RoomMessage); room->sendMessageEvent(audio, mtx::events::EventType::RoomMessage);
} }
@ -431,6 +462,11 @@ InputBar::video(const QString &filename,
{mtx::common::RelationType::InReplyTo, room->reply().toStdString()}); {mtx::common::RelationType::InReplyTo, room->reply().toStdString()});
room->resetReply(); room->resetReply();
} }
if (!room->edit().isEmpty()) {
video.relations.relations.push_back(
{mtx::common::RelationType::Replace, room->edit().toStdString()});
room->resetEdit();
}
room->sendMessageEvent(video, mtx::events::EventType::RoomMessage); room->sendMessageEvent(video, mtx::events::EventType::RoomMessage);
} }
@ -524,6 +560,8 @@ InputBar::showPreview(const QMimeData &source, QString path, const QStringList &
[this](const QByteArray data, const QString &mime, const QString &fn) { [this](const QByteArray data, const QString &mime, const QString &fn) {
setUploading(true); setUploading(true);
setText("");
auto payload = std::string(data.data(), data.size()); auto payload = std::string(data.data(), data.size());
std::optional<mtx::crypto::EncryptedFile> encryptedFile; std::optional<mtx::crypto::EncryptedFile> encryptedFile;
if (cache::isRoomEncrypted(room->roomId().toStdString())) { if (cache::isRoomEncrypted(room->roomId().toStdString())) {

View file

@ -41,6 +41,7 @@ public slots:
QString text() const; QString text() const;
QString previousText(); QString previousText();
QString nextText(); QString nextText();
void setText(QString newText) { emit textChanged(newText); }
void send(); void send();
void paste(bool fromMouse); void paste(bool fromMouse);
@ -58,6 +59,7 @@ private slots:
signals: signals:
void insertText(QString text); void insertText(QString text);
void textChanged(QString newText);
void uploadingChanged(bool value); void uploadingChanged(bool value);
private: private:

View file

@ -1529,11 +1529,33 @@ TimelineModel::setEdit(QString newEdit)
if (ev) { if (ev) {
setReply(QString::fromStdString( setReply(QString::fromStdString(
mtx::accessors::relations(*ev).reply_to().value_or(""))); mtx::accessors::relations(*ev).reply_to().value_or("")));
// input()->setText(mtx::accessors::body(*ev));
auto msgType = mtx::accessors::msg_type(*ev);
if (msgType == mtx::events::MessageType::Text ||
msgType == mtx::events::MessageType::Notice) {
input()->setText(relatedInfo(newEdit).quoted_body);
} else if (msgType == mtx::events::MessageType::Emote) {
input()->setText("/me " + relatedInfo(newEdit).quoted_body);
} else {
input()->setText("");
}
} else {
input()->setText("");
} }
} }
} }
void
TimelineModel::resetEdit()
{
if (!edit_.isEmpty()) {
edit_ = "";
emit editChanged(edit_);
input()->setText("");
resetReply();
}
}
QString QString
TimelineModel::roomName() const TimelineModel::roomName() const
{ {

View file

@ -274,14 +274,7 @@ public slots:
} }
QString edit() const { return edit_; } QString edit() const { return edit_; }
void setEdit(QString newEdit); void setEdit(QString newEdit);
void resetEdit() void resetEdit();
{
if (!edit_.isEmpty()) {
edit_ = "";
emit editChanged(edit_);
resetReply();
}
}
void setDecryptDescription(bool decrypt) { decryptDescription = decrypt; } void setDecryptDescription(bool decrypt) { decryptDescription = decrypt; }
void clearTimeline() { events.clearTimeline(); } void clearTimeline() { events.clearTimeline(); }
void receivedSessionKey(const std::string &session_key) void receivedSessionKey(const std::string &session_key)