Warning, /network/neochat/src/qml/MessageEditComponent.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
0002 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0003 
0004 import QtQuick
0005 import QtQuick.Controls as QQC2
0006 import QtQuick.Layouts
0007 
0008 import org.kde.kirigami as Kirigami
0009 
0010 import org.kde.neochat
0011 
0012 QQC2.TextArea {
0013     id: root
0014 
0015     required property NeoChatRoom room
0016     onRoomChanged: {
0017         _private.chatBarCache = room.editCache;
0018         _private.chatBarCache.relationIdChanged.connect(_private.updateEditText);
0019     }
0020 
0021     /**
0022      * @brief The ActionsHandler object to use.
0023      *
0024      * This is expected to have the correct room set otherwise messages will be sent
0025      * to the wrong room.
0026      */
0027     required property ActionsHandler actionsHandler
0028 
0029     property string messageId
0030 
0031     property var minimumHeight: editButtons.height + topPadding + bottomPadding
0032     property var preferredWidth: editTextMetrics.advanceWidth + rightPadding + Kirigami.Units.smallSpacing + Kirigami.Units.gridUnit
0033     rightPadding: editButtons.width + editButtons.anchors.rightMargin * 2
0034 
0035     color: Kirigami.Theme.textColor
0036     verticalAlignment: TextEdit.AlignVCenter
0037     wrapMode: TextEdit.Wrap
0038 
0039     onTextChanged: {
0040         _private.chatBarCache.text = text;
0041     }
0042 
0043     Keys.onEnterPressed: {
0044         if (completionMenu.visible) {
0045             completionMenu.complete();
0046         } else if (event.modifiers & Qt.ShiftModifier) {
0047             root.insert(cursorPosition, "\n");
0048         } else {
0049             root.postEdit();
0050         }
0051     }
0052     Keys.onReturnPressed: {
0053         if (completionMenu.visible) {
0054             completionMenu.complete();
0055         } else if (event.modifiers & Qt.ShiftModifier) {
0056             root.insert(cursorPosition, "\n");
0057         } else {
0058             root.postEdit();
0059         }
0060     }
0061     Keys.onTabPressed: {
0062         if (completionMenu.visible) {
0063             completionMenu.complete();
0064         }
0065     }
0066     Keys.onPressed: event => {
0067         if (event.key === Qt.Key_Up && completionMenu.visible) {
0068             completionMenu.decrementIndex();
0069         } else if (event.key === Qt.Key_Down && completionMenu.visible) {
0070             completionMenu.incrementIndex();
0071         }
0072     }
0073 
0074     /**
0075     * This is anchored like this so that control expands properly as the edited
0076     * text grows in length.
0077     */
0078     RowLayout {
0079         id: editButtons
0080         anchors.verticalCenter: root.verticalCenter
0081         anchors.right: root.right
0082         anchors.rightMargin: Kirigami.Units.smallSpacing
0083         spacing: 0
0084         QQC2.ToolButton {
0085             display: QQC2.AbstractButton.IconOnly
0086             action: Kirigami.Action {
0087                 text: i18nc("@action:button", "Confirm edit")
0088                 icon.name: "checkmark"
0089                 onTriggered: {
0090                     root.postEdit();
0091                 }
0092             }
0093             QQC2.ToolTip.text: text
0094             QQC2.ToolTip.visible: hovered
0095         }
0096         QQC2.ToolButton {
0097             display: QQC2.AbstractButton.IconOnly
0098             action: Kirigami.Action {
0099                 text: i18nc("@action:button", "Cancel edit")
0100                 icon.name: "dialog-close"
0101                 onTriggered: {
0102                     _private.chatBarCache.editId = "";
0103                 }
0104                 shortcut: "Escape"
0105             }
0106             QQC2.ToolTip.text: text
0107             QQC2.ToolTip.visible: hovered
0108         }
0109     }
0110 
0111     CompletionMenu {
0112         id: completionMenu
0113         height: implicitHeight
0114         y: -height - 5
0115         z: 10
0116         connection: root.room.connection
0117         chatDocumentHandler: documentHandler
0118         Behavior on height {
0119             NumberAnimation {
0120                 property: "height"
0121                 duration: Kirigami.Units.shortDuration
0122                 easing.type: Easing.OutCubic
0123             }
0124         }
0125     }
0126 
0127     // opt-out of whatever spell checker a styled TextArea might come with
0128     Kirigami.SpellCheck.enabled: false
0129 
0130     ChatDocumentHandler {
0131         id: documentHandler
0132         document: root.textDocument
0133         cursorPosition: root.cursorPosition
0134         selectionStart: root.selectionStart
0135         selectionEnd: root.selectionEnd
0136         room: root.room // We don't care about saving for edits so this is OK.
0137         mentionColor: Kirigami.Theme.linkColor
0138         errorColor: Kirigami.Theme.negativeTextColor
0139     }
0140 
0141     TextMetrics {
0142         id: editTextMetrics
0143         text: root.text
0144     }
0145 
0146     function postEdit() {
0147         root.actionsHandler.handleMessageEvent(_private.chatBarCache);
0148         root.clear();
0149         _private.chatBarCache.editId = "";
0150     }
0151 
0152     QtObject {
0153         id: _private
0154         property ChatBarCache chatBarCache
0155         onChatBarCacheChanged: documentHandler.chatBarCache = chatBarCache
0156 
0157         function updateEditText() {
0158             if (chatBarCache?.isEditing && chatBarCache.relationMessage.length > 0) {
0159                 root.text = chatBarCache.relationMessage;
0160                 root.forceActiveFocus();
0161                 root.cursorPosition = root.length;
0162             }
0163         }
0164     }
0165 }