Inline Edits
Edit text messages inline instead of in the chatbar
This commit is contained in:
@@ -14,9 +14,7 @@ QQC2.Control {
|
||||
|
||||
property alias textField: textField
|
||||
property bool isReplying: currentRoom.chatBoxReplyId.length > 0
|
||||
property bool isEditing: currentRoom.chatBoxEditId.length > 0
|
||||
property bool replyPaneVisible: isReplying || isEditing
|
||||
property NeoChatUser replyUser: currentRoom.chatBoxReplyUser ?? currentRoom.chatBoxEditUser
|
||||
property NeoChatUser replyUser: currentRoom.chatBoxReplyUser
|
||||
property bool attachmentPaneVisible: currentRoom.chatBoxAttachmentPath.length > 0
|
||||
|
||||
signal messageSent()
|
||||
@@ -122,7 +120,7 @@ QQC2.Control {
|
||||
leftPadding: LayoutMirroring.enabled ? actionsRow.width : (root.width > chatBoxMaxWidth ? 0 : Kirigami.Units.largeSpacing)
|
||||
rightPadding: LayoutMirroring.enabled ? (root.width > chatBoxMaxWidth ? 0 : Kirigami.Units.largeSpacing) : actionsRow.width
|
||||
|
||||
placeholderText: readOnly ? i18n("This room is encrypted. Build libQuotient with encryption enabled to send encrypted messages.") : currentRoom.chatBoxEditId.length > 0 ? i18n("Edit Message") : currentRoom.usesEncryption ? i18n("Send an encrypted message…") : currentRoom.chatBoxAttachmentPath.length > 0 ? i18n("Set an attachment caption...") : i18n("Send a message…")
|
||||
placeholderText: readOnly ? i18n("This room is encrypted. Build libQuotient with encryption enabled to send encrypted messages.") : currentRoom.usesEncryption ? i18n("Send an encrypted message…") : currentRoom.chatBoxAttachmentPath.length > 0 ? i18n("Set an attachment caption...") : i18n("Send a message…")
|
||||
verticalAlignment: TextEdit.AlignVCenter
|
||||
wrapMode: Text.Wrap
|
||||
readOnly: (currentRoom.usesEncryption && !Controller.encryptionSupported)
|
||||
@@ -198,8 +196,8 @@ QQC2.Control {
|
||||
anchors.rightMargin: root.width > chatBoxMaxWidth ? 0 : (chatBarScrollView.QQC2.ScrollBar.vertical.visible ? Kirigami.Units.largeSpacing * 3.5 : Kirigami.Units.largeSpacing)
|
||||
|
||||
active: visible
|
||||
visible: root.replyPaneVisible || root.attachmentPaneVisible
|
||||
sourceComponent: root.replyPaneVisible ? replyPane : attachmentPane
|
||||
visible: root.isReplying || root.attachmentPaneVisible
|
||||
sourceComponent: root.isReplying ? replyPane : attachmentPane
|
||||
}
|
||||
Component {
|
||||
id: replyPane
|
||||
@@ -207,8 +205,7 @@ QQC2.Control {
|
||||
userName: root.replyUser ? root.replyUser.displayName : ""
|
||||
userColor: root.replyUser ? root.replyUser.color : ""
|
||||
userAvatar: root.replyUser ? "image://mxc/" + currentRoom.getUser(root.replyUser.id).avatarMediaId : ""
|
||||
isReply: root.isReplying
|
||||
text: isEditing ? currentRoom.chatBoxEditMessage : currentRoom.chatBoxReplyMessage
|
||||
text: currentRoom.chatBoxReplyMessage
|
||||
}
|
||||
}
|
||||
Component {
|
||||
@@ -263,14 +260,13 @@ QQC2.Control {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: (root.width - chatBoxMaxWidth) / 2 + Kirigami.Units.largeSpacing + (chatBarScrollView.QQC2.ScrollBar.vertical.visible && !(root.width > chatBoxMaxWidth) ? Kirigami.Units.largeSpacing * 2.5 : 0)
|
||||
|
||||
visible: root.replyPaneVisible
|
||||
visible: root.isReplying
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
action: Kirigami.Action {
|
||||
text: root.isReplying ? i18nc("@action:button", "Cancel reply") : i18nc("@action:button", "Cancel edit")
|
||||
text: i18nc("@action:button", "Cancel reply")
|
||||
icon.name: "dialog-close"
|
||||
onTriggered: {
|
||||
currentRoom.chatBoxReplyId = "";
|
||||
currentRoom.chatBoxEditId = "";
|
||||
currentRoom.chatBoxAttachmentPath = "";
|
||||
root.forceActiveFocus()
|
||||
}
|
||||
@@ -356,15 +352,6 @@ QQC2.Control {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: currentRoom
|
||||
function onChatBoxEditIdChanged() {
|
||||
if (currentRoom.chatBoxEditMessage.length > 0) {
|
||||
textField.text = currentRoom.chatBoxEditMessage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ChatDocumentHandler {
|
||||
id: documentHandler
|
||||
document: textField.textDocument
|
||||
@@ -398,12 +385,11 @@ QQC2.Control {
|
||||
}
|
||||
|
||||
function postMessage() {
|
||||
actionsHandler.handleMessage();
|
||||
actionsHandler.handleNewMessage();
|
||||
repeatTimer.stop()
|
||||
currentRoom.markAllMessagesAsRead();
|
||||
textField.clear();
|
||||
currentRoom.chatBoxReplyId = "";
|
||||
currentRoom.chatBoxEditId = "";
|
||||
messageSent()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ QQC2.Popup {
|
||||
connection: Controller.activeConnection
|
||||
}
|
||||
|
||||
required property var chatDocumentHandler
|
||||
property var chatDocumentHandler
|
||||
Component.onCompleted: {
|
||||
chatDocumentHandler.completionModel.roomListModel = roomListModel;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ GridLayout {
|
||||
property string userName
|
||||
property color userColor: Kirigami.Theme.highlightColor
|
||||
property var userAvatar: ""
|
||||
property bool isReply
|
||||
property var text
|
||||
|
||||
rows: 3
|
||||
@@ -30,7 +29,7 @@ GridLayout {
|
||||
Layout.columnSpan: 3
|
||||
topPadding: Kirigami.Units.smallSpacing
|
||||
|
||||
text: isReply ? i18n("Replying to:") : i18n("Editing message:")
|
||||
text: i18n("Replying to:")
|
||||
}
|
||||
Rectangle {
|
||||
id: verticalBorder
|
||||
|
||||
@@ -21,8 +21,14 @@ TimelineContainer {
|
||||
RichLabel {
|
||||
id: label
|
||||
Layout.fillWidth: true
|
||||
visible: currentRoom.chatBoxEditId !== model.eventId
|
||||
isEmote: messageDelegate.isEmote
|
||||
}
|
||||
MessageEditComponent {
|
||||
Layout.fillWidth: true
|
||||
messageId: model.eventId
|
||||
visible: currentRoom.chatBoxEditId === model.eventId
|
||||
}
|
||||
Loader {
|
||||
id: linkPreviewLoader
|
||||
Layout.fillWidth: true
|
||||
|
||||
149
src/qml/Component/Timeline/MessageEditComponent.qml
Normal file
149
src/qml/Component/Timeline/MessageEditComponent.qml
Normal file
@@ -0,0 +1,149 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
QQC2.TextArea {
|
||||
id: root
|
||||
|
||||
property string messageId
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: editButtons.height + topPadding + bottomPadding
|
||||
Layout.preferredWidth: editTextMetrics.advanceWidth + rightPadding + Kirigami.Units.smallSpacing + Kirigami.Units.gridUnit
|
||||
rightPadding: editButtons.width + editButtons.anchors.rightMargin * 2
|
||||
|
||||
color: Kirigami.Theme.textColor
|
||||
verticalAlignment: TextEdit.AlignVCenter
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
forceActiveFocus();
|
||||
root.cursorPosition = root.length;
|
||||
}
|
||||
}
|
||||
onTextChanged: {
|
||||
currentRoom.editText = text
|
||||
}
|
||||
|
||||
Keys.onEnterPressed: {
|
||||
if (completionMenu.visible) {
|
||||
completionMenu.complete()
|
||||
} else if (event.modifiers & Qt.ShiftModifier) {
|
||||
root.insert(cursorPosition, "\n")
|
||||
} else {
|
||||
root.postEdit();
|
||||
}
|
||||
}
|
||||
Keys.onReturnPressed: {
|
||||
if (completionMenu.visible) {
|
||||
completionMenu.complete()
|
||||
} else if (event.modifiers & Qt.ShiftModifier) {
|
||||
root.insert(cursorPosition, "\n")
|
||||
} else {
|
||||
root.postEdit();
|
||||
}
|
||||
}
|
||||
Keys.onTabPressed: {
|
||||
if (completionMenu.visible) {
|
||||
completionMenu.complete()
|
||||
}
|
||||
}
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Up && completionMenu.visible) {
|
||||
completionMenu.decrementIndex()
|
||||
} else if (event.key === Qt.Key_Down && completionMenu.visible) {
|
||||
completionMenu.incrementIndex()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is anchored like this so that control expands properly as the edited
|
||||
* text grows in length.
|
||||
*/
|
||||
RowLayout {
|
||||
id: editButtons
|
||||
anchors.verticalCenter: root.verticalCenter
|
||||
anchors.right: root.right
|
||||
anchors.rightMargin: Kirigami.Units.smallSpacing
|
||||
spacing: 0
|
||||
QQC2.ToolButton {
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
action: Kirigami.Action {
|
||||
text: i18nc("@action:button", "Confirm edit")
|
||||
icon.name: "checkmark"
|
||||
onTriggered: {
|
||||
root.postEdit();
|
||||
}
|
||||
}
|
||||
QQC2.ToolTip.text: text
|
||||
QQC2.ToolTip.visible: hovered
|
||||
}
|
||||
QQC2.ToolButton {
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
action: Kirigami.Action {
|
||||
text: i18nc("@action:button", "Cancel edit")
|
||||
icon.name: "dialog-close"
|
||||
onTriggered: {
|
||||
currentRoom.chatBoxEditId = "";
|
||||
}
|
||||
shortcut: "Escape"
|
||||
}
|
||||
QQC2.ToolTip.text: text
|
||||
QQC2.ToolTip.visible: hovered
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: currentRoom
|
||||
function onChatBoxEditIdChanged() {
|
||||
if (currentRoom.chatBoxEditId == messageId && currentRoom.chatBoxEditMessage.length > 0) {
|
||||
root.text = currentRoom.chatBoxEditMessage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CompletionMenu {
|
||||
id: completionMenu
|
||||
height: implicitHeight
|
||||
y: -height - 5
|
||||
z: 10
|
||||
chatDocumentHandler: documentHandler
|
||||
Behavior on height {
|
||||
NumberAnimation {
|
||||
property: "height"
|
||||
duration: Kirigami.Units.shortDuration
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ChatDocumentHandler {
|
||||
id: documentHandler
|
||||
isEdit: true
|
||||
document: root.textDocument
|
||||
cursorPosition: root.cursorPosition
|
||||
selectionStart: root.selectionStart
|
||||
selectionEnd: root.selectionEnd
|
||||
room: currentRoom // We don't care about saving for edits so this is OK.
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: editTextMetrics
|
||||
text: root.text
|
||||
}
|
||||
|
||||
function postEdit() {
|
||||
actionsHandler.handleEdit();
|
||||
root.clear();
|
||||
currentRoom.chatBoxEditId = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -540,7 +540,6 @@ Kirigami.ScrollablePage {
|
||||
onClicked: {
|
||||
currentRoom.chatBoxEditId = hoverActions.event.eventId;
|
||||
currentRoom.chatBoxReplyId = "";
|
||||
chatBox.chatBar.forceActiveFocus();
|
||||
}
|
||||
}
|
||||
QQC2.Button {
|
||||
|
||||
Reference in New Issue
Block a user