Page MenuHomePhorge

No OneTemporary

Size
15 KB
Referenced Files
None
Subscribers
None
diff --git a/src/contents/ui/SendMessageBox.qml b/src/contents/ui/SendMessageBox.qml
index f9c8138..4a79248 100644
--- a/src/contents/ui/SendMessageBox.qml
+++ b/src/contents/ui/SendMessageBox.qml
@@ -1,388 +1,395 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2020-2023 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15
import org.kde.kirigami 2.13 as Kirigami
import moe.kazv.mxc.kazv 0.0 as MK
import '.' as Kazv
ColumnLayout {
id: sendMessageBox
property var room
property var draftRelType: ''
property var draftRelatedTo: ''
property var timeline: room.timeline()
property var members: room.members()
function getRelationPrompt(draftRelType) {
if (draftRelType === 'm.in_reply_to') {
return l10n.get('send-message-box-reply-to');
} else if (draftRelType === 'm.replace') {
return l10n.get('send-message-box-edit');
}
}
function getCancelRelationPrompt(draftRelType) {
if (draftRelType === 'm.in_reply_to') {
return l10n.get('send-message-box-remove-reply-to-action');
} else if (draftRelType === 'm.replace') {
return l10n.get('send-message-box-remove-replace-action');
}
}
function replaceDraft(newDraft) {
textArea.changeText(newDraft, /* inhibitTyping = */ true);
}
onRoomChanged: {
textArea.changeText(room.localDraft, true);
}
Popup {
id: completionPopup
objectName: 'completionPopup'
x: 1
y: -height
width: parent.width - 1
contentItem: Kazv.Completion {
id: completion
members: sendMessageBox.members
onMentionUserRequested: (userId) => {
textArea.removePartialMention();
sendMessageBox.mentionUser(userId);
}
}
}
Control {
visible: !!sendMessageBox.draftRelatedTo
Layout.fillWidth: true
background: Rectangle {
color: Kirigami.Theme.alternateBackgroundColor
}
contentItem: RowLayout {
spacing: 0
ColumnLayout {
Layout.fillWidth: true
Label {
id: replyLabel
Layout.leftMargin: Kirigami.Units.largeSpacing
Layout.topMargin: Kirigami.Units.largeSpacing
Layout.fillWidth: true
text: getRelationPrompt(sendMessageBox.draftRelType)
}
Item {
id: replyItem
Layout.minimumHeight: Math.min(replyToEventView.implicitHeight, Kirigami.Units.gridUnit * 5)
Layout.maximumHeight: Kirigami.Units.gridUnit * 5
Layout.fillWidth: true
clip: true
Kazv.EventViewWrapper {
id: replyToEventView
anchors {
top: parent.top
left: parent.left
right: parent.right
}
event: room.messageById(sendMessageBox.draftRelatedTo)
compactMode: true
}
}
}
ToolButton {
Layout.alignment: Qt.AlignTop
action: removeRelatedToAction
display: AbstractButton.IconOnly
}
}
}
RowLayout {
- TextArea {
- id: textArea
- objectName: 'draftMessage'
- property var shortcutList: ["Ctrl+Return", "Ctrl+Enter"]
- property var inhibitTyping: false
- placeholderText: l10n.get('send-message-box-input-placeholder')
- property string filter: getFilter()
+ ScrollView {
Layout.fillWidth: true
- wrapMode: TextEdit.Wrap
- persistentSelection: true
- onTextChanged: {
- room.setLocalDraft(text);
- if (!inhibitTyping) {
- room.setTyping(true);
+ ScrollBar.vertical.policy: ScrollBar.AsNeeded
+ Layout.preferredHeight: textArea.implicitHeight
+ Layout.maximumHeight: Kirigami.Units.gridUnit * 8
+
+ TextArea {
+ id: textArea
+ objectName: 'draftMessage'
+ property var shortcutList: ["Ctrl+Return", "Ctrl+Enter"]
+ property var inhibitTyping: false
+ placeholderText: l10n.get('send-message-box-input-placeholder')
+ property string filter: getFilter()
+ Layout.fillWidth: true
+ wrapMode: TextEdit.Wrap
+ persistentSelection: true
+ onTextChanged: {
+ room.setLocalDraft(text);
+ if (!inhibitTyping) {
+ room.setTyping(true);
+ }
+ inhibitTyping = false;
}
- inhibitTyping = false;
- }
-
- function changeText(newText, inhibitTyping) {
- textArea.inhibitTyping = inhibitTyping;
- textArea.text = newText;
- }
- onVisibleChanged: {
- if (!visible) {
- room.updateLocalDraftNow();
+ function changeText(newText, inhibitTyping) {
+ textArea.inhibitTyping = inhibitTyping;
+ textArea.text = newText;
}
- }
- function getFilter() {
- const atPos = text.lastIndexOf('@', cursorPosition);
- if (atPos < 0) {
- return '';
+ onVisibleChanged: {
+ if (!visible) {
+ room.updateLocalDraftNow();
+ }
}
- const textInBetween = text.slice(atPos, cursorPosition);
- const hasSpaces = /\s/.test(textInBetween);
- return hasSpaces ? '' : textInBetween;
- }
-
- function removePartialMention() {
- const atPos = text.lastIndexOf('@', cursorPosition);
- text = text.slice(0, atPos) + text.slice(cursorPosition);
- cursorPosition = atPos;
- }
+ function getFilter() {
+ const atPos = text.lastIndexOf('@', cursorPosition);
+ if (atPos < 0) {
+ return '';
+ }
- onFilterChanged: {
- sendMessageBox.members.filter = filter.slice(1);
- if (filter && sendMessageBox.members.count > 0) {
- completionPopup.open();
- } else {
- completionPopup.close();
+ const textInBetween = text.slice(atPos, cursorPosition);
+ const hasSpaces = /\s/.test(textInBetween);
+ return hasSpaces ? '' : textInBetween;
}
- }
- // Shortcut keys for sending messages (TODO: Shortcut keys customized by the user)
- Shortcut {
- sequences: textArea.shortcutList
- onActivated: {
- sendAction.trigger()
+ function removePartialMention() {
+ const atPos = text.lastIndexOf('@', cursorPosition);
+ text = text.slice(0, atPos) + text.slice(cursorPosition);
+ cursorPosition = atPos;
}
- }
- DropArea {
- anchors.fill: parent
- onDropped: (drag) => {
- if (drag.hasUrls) {
- confirmUploadPopup.call(drag.urls);
+ onFilterChanged: {
+ sendMessageBox.members.filter = filter.slice(1);
+ if (filter && sendMessageBox.members.count > 0) {
+ completionPopup.open();
+ } else {
+ completionPopup.close();
}
}
- }
- function handlePaste() {
- if (MK.KazvClipboard.hasUrls) {
- confirmUploadPopup.call(MK.KazvClipboard.urls());
- } else if (MK.KazvClipboard.hasImage) {
- confirmUploadPopup.call([ MK.KazvClipboard.saveClipboardImage() ]);
- } else {
- textArea.paste();
- }
- }
- Keys.onPressed: (event) => {
- if (event.matches(StandardKey.Paste)) {
- textArea.handlePaste();
- event.accepted = true;
+ // Shortcut keys for sending messages (TODO: Shortcut keys customized by the user)
+ Shortcut {
+ sequences: textArea.shortcutList
+ onActivated: {
+ sendAction.trigger()
+ }
}
- }
- MouseArea {
- anchors.fill: parent
- acceptedButtons: Qt.RightButton
- preventStealing: true
- cursorShape: Qt.IBeamCursor
- onClicked: (mouse) => {
- if (mouse.button === Qt.RightButton)
- textAreaMenu.popup();
+ DropArea {
+ anchors.fill: parent
+ onDropped: (drag) => {
+ if (drag.hasUrls) {
+ confirmUploadPopup.call(drag.urls);
+ }
+ }
}
- Menu {
- id: textAreaMenu
- MenuItem {
- text: l10n.get("action-undo")
- icon.name: "edit-undo"
- onTriggered: textArea.undo()
- enabled: textArea.canUndo
- }
- MenuItem {
- text: l10n.get("action-redo")
- icon.name: "edit-redo"
- onTriggered: textArea.redo()
- enabled: textArea.canRedo
- }
- MenuSeparator {}
- MenuItem {
- text: l10n.get("action-cut")
- icon.name: "edit-cut"
- onTriggered: textArea.cut()
- enabled: !!textArea.selectedText
+ function handlePaste() {
+ if (MK.KazvClipboard.hasUrls) {
+ confirmUploadPopup.call(MK.KazvClipboard.urls());
+ } else if (MK.KazvClipboard.hasImage) {
+ confirmUploadPopup.call([ MK.KazvClipboard.saveClipboardImage() ]);
+ } else {
+ textArea.paste();
}
- MenuItem {
- text: l10n.get("action-copy")
- icon.name: "edit-copy"
- onTriggered: textArea.copy()
- enabled: !!textArea.selectedText
- }
- MenuItem {
- text: l10n.get("action-paste")
- icon.name: "edit-paste"
- onTriggered: textArea.handlePaste()
- enabled: textArea.canPaste || MK.KazvClipboard.hasImage || MK.KazvClipboard.hasUrls
+ }
+ Keys.onPressed: (event) => {
+ if (event.matches(StandardKey.Paste)) {
+ textArea.handlePaste();
+ event.accepted = true;
}
- MenuItem {
- text: l10n.get("action-delete")
- icon.name: "edit-delete"
- onTriggered: textArea.remove(textArea.selectionStart, textArea.selectionEnd)
- enabled: !!textArea.selectedText
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ acceptedButtons: Qt.RightButton
+ preventStealing: true
+ cursorShape: Qt.IBeamCursor
+ onClicked: (mouse) => {
+ if (mouse.button === Qt.RightButton)
+ textAreaMenu.popup();
}
- MenuItem {
- text: l10n.get("action-select-all")
- icon.name: "edit-select-all"
- onTriggered: textArea.selectAll()
+
+ Menu {
+ id: textAreaMenu
+ MenuItem {
+ text: l10n.get("action-undo")
+ icon.name: "edit-undo"
+ onTriggered: textArea.undo()
+ enabled: textArea.canUndo
+ }
+ MenuItem {
+ text: l10n.get("action-redo")
+ icon.name: "edit-redo"
+ onTriggered: textArea.redo()
+ enabled: textArea.canRedo
+ }
+ MenuSeparator {}
+ MenuItem {
+ text: l10n.get("action-cut")
+ icon.name: "edit-cut"
+ onTriggered: textArea.cut()
+ enabled: !!textArea.selectedText
+ }
+ MenuItem {
+ text: l10n.get("action-copy")
+ icon.name: "edit-copy"
+ onTriggered: textArea.copy()
+ enabled: !!textArea.selectedText
+ }
+ MenuItem {
+ text: l10n.get("action-paste")
+ icon.name: "edit-paste"
+ onTriggered: textArea.handlePaste()
+ enabled: textArea.canPaste || MK.KazvClipboard.hasImage || MK.KazvClipboard.hasUrls
+ }
+ MenuItem {
+ text: l10n.get("action-delete")
+ icon.name: "edit-delete"
+ onTriggered: textArea.remove(textArea.selectionStart, textArea.selectionEnd)
+ enabled: !!textArea.selectedText
+ }
+ MenuItem {
+ text: l10n.get("action-select-all")
+ icon.name: "edit-select-all"
+ onTriggered: textArea.selectAll()
+ }
}
}
}
}
ToolButton {
action: sendMediaFileAction
objectName: 'sendMediaFileButton'
display: AbstractButton.IconOnly
}
ToolButton {
action: stickersAction
display: AbstractButton.IconOnly
}
ToolButton {
objectName: 'sendButton'
action: sendAction
display: AbstractButton.IconOnly
}
}
function mentionUser(userId) {
const prefix = textArea.text.slice(0, textArea.cursorPosition);
const suffix = textArea.text.slice(textArea.cursorPosition);
let insertion = userId;
// If we are not at the beginning and the prev char is not a space,
// insert a space there.
if (prefix && prefix.slice(prefix.length - 1).trim() !== '') {
insertion = ' ' + insertion;
}
let postPadding = 0;
// If we are at the end or the next char is not a space,
// insert a space there.
if (!suffix || suffix.slice(0, 1).trim() !== '') {
insertion = insertion + ' ';
} else if (suffix) {
// If there is a suffix, and space is not inserted
// this means the next character is a space,
// move the cursor to that space.
postPadding = 1;
}
textArea.text = prefix + insertion + suffix;
textArea.cursorPosition = prefix.length + insertion.length + postPadding;
}
function focusInput() {
textArea.forceActiveFocus();
}
Kirigami.Action {
id: removeRelatedToAction
icon.name: 'window-close-symbolic'
text: getCancelRelationPrompt(sendMessageBox.draftRelType)
onTriggered: {
sendMessageBox.draftRelType = '';
sendMessageBox.draftRelatedTo = '';
}
}
Kirigami.Action {
id: sendAction
icon.name: "document-send"
text: l10n.get("send-message-box-send")
onTriggered: {
room.setTyping(false);
room.sendTextMessage(textArea.text, draftRelType, draftRelatedTo);
textArea.changeText("", true);
sendMessageBox.draftRelType = '';
sendMessageBox.draftRelatedTo = '';
}
enabled: textArea.text !== ''
}
Kirigami.Action {
id: sendMediaFileAction
icon.name: "document-open-data"
text: l10n.get("send-message-box-send-file")
onTriggered: {
fileDialog.open()
}
}
property var confirmUploadPopup: ConfirmUploadPopup {
id: confirmUploadPopup
parent: applicationWindow().overlay
onUploadRequested: (url) => {
sendMessageBox.uploadFile(url);
}
}
property var fileDialog: Kazv.FileDialogAdapter {
objectName: 'fileDialog'
onAccepted: {
sendMessageBox.uploadFile(fileUrl);
}
}
function uploadFile(fileUrl) {
kazvIOManager.startNewUploadJob(
matrixSdk.serverUrl, fileUrl, matrixSdk.token,
room.roomId, sdkVars.roomList, room.encrypted,
draftRelType, draftRelatedTo
);
sendMessageBox.draftRelType = '';
sendMessageBox.draftRelatedTo = '';
}
property var stickerPopup: Kirigami.OverlaySheet {
id: stickerPopup
parent: applicationWindow().overlay
title: l10n.get('send-message-box-stickers-popup-title')
Kazv.StickerPicker {
Layout.preferredWidth: Math.min(Kirigami.Units.gridUnit * 40, Window.width)
stickerPackList: matrixSdk.stickerPackList()
onSendMessageRequested: eventJson => {
console.log(JSON.stringify(eventJson));
room.sendMessage(eventJson, draftRelType, draftRelatedTo);
draftRelType = '';
draftRelatedTo = '';
stickerPopup.close();
}
}
}
Kirigami.Action {
id: stickersAction
icon.name: 'smiley'
text: l10n.get('send-message-box-stickers')
onTriggered: stickerPopup.open()
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jul 19, 4:16 PM (1 d, 22 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1695311
Default Alt Text
(15 KB)

Event Timeline