diff --git a/imports/NeoChat/Component/ChatTextInput.qml b/imports/NeoChat/Component/ChatTextInput.qml
index 7557f1302..71b45f6a4 100644
--- a/imports/NeoChat/Component/ChatTextInput.qml
+++ b/imports/NeoChat/Component/ChatTextInput.qml
@@ -133,6 +133,7 @@ ToolBar {
keyNavigationWraps: true
delegate: Control {
+ property string autoCompleteText: modelData.displayName ? ("[" + modelData.displayName + "](https://matrix.to/#/" + modelData.id + "):") : modelData.unicode
property string displayText: modelData.displayName ?? modelData.unicode
property bool isEmoji: modelData.unicode != null
readonly property bool highlighted: autoCompleteListView.currentIndex == index
@@ -176,7 +177,7 @@ ToolBar {
anchors.fill: parent
onClicked: {
autoCompleteListView.currentIndex = index
- documentHandler.replaceAutoComplete(displayText)
+ inputField.autoComplete();
}
}
}
@@ -303,6 +304,7 @@ ToolBar {
wrapMode: Text.Wrap
placeholderText: i18n("Write your message...")
+ textFormat: TextEdit.MarkdownText
topPadding: 0
bottomPadding: 0
leftPadding: Kirigami.Units.smallSpacing
@@ -342,7 +344,8 @@ ToolBar {
Keys.onReturnPressed: {
if (isAutoCompleting) {
- documentHandler.replaceAutoComplete(autoCompleteListView.currentItem.displayText)
+ inputField.autoComplete();
+
isAutoCompleting = false;
return;
}
@@ -397,7 +400,7 @@ ToolBar {
autoAppeared = false;
}
- documentHandler.replaceAutoComplete(autoCompleteListView.currentItem.displayText)
+ inputField.autoComplete();
}
onTextChanged: {
@@ -434,10 +437,33 @@ ToolBar {
}
function postMessage() {
- documentHandler.postMessage(inputField.text, attachmentPath, replyEventID);
+ // Qt wraps lines so we need to use a small hack
+ // to remove the wrapped lines but not break the empty
+ // lines.
+ const updatedText = inputField.text.trim()
+ .replace(/\n{2,}/g, '
')
+ .replace(/\n/g, '')
+ documentHandler.postMessage(updatedText, attachmentPath, replyEventID);
clearAttachment();
currentRoom.markAllMessagesAsRead();
clear();
+ text = Qt.binding(function() {
+ return currentRoom != null ? currentRoom.cachedInput : "";
+ });
+ }
+
+ // HACK apply markdown, we are setting the text attribute to
+ // force the text field to rerender. Because the cursor position
+ // will be reset, we save the old one and substract the now hidden
+ // markdown markup.
+ function autoComplete() {
+ documentHandler.replaceAutoComplete(autoCompleteListView.currentItem.autoCompleteText)
+ const oldCursorPosition = cursorPosition;
+ const oldText = text;
+ const oldLength = inputField.length;
+ text = "";
+ text = oldText;
+ cursorPosition = oldCursorPosition - (oldLength - inputField.length);
}
}
diff --git a/src/neochatroom.cpp b/src/neochatroom.cpp
index 4e0320032..af6119762 100644
--- a/src/neochatroom.cpp
+++ b/src/neochatroom.cpp
@@ -467,6 +467,8 @@ QString NeoChatRoom::markdownToHTML(const QString &markdown)
auto result = QString::fromStdString(html).trimmed();
+ result.replace("", "
");
+ result.replace(QRegularExpression("(
)*$"), "");
result.replace("
", ""); result.replace("
", "");