Page MenuHomePhorge

SendMessageBox.qml
No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None

SendMessageBox.qml

/*
* 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);
}
}
}
ColumnLayout {
visible: !!sendMessageBox.draftRelatedTo
RowLayout {
Label {
Layout.fillWidth: true
text: getRelationPrompt(sendMessageBox.draftRelType)
}
ToolButton {
action: removeRelatedToAction
display: AbstractButton.IconOnly
}
}
Item {
Layout.minimumHeight: Math.min(replyToEventView.implicitHeight, Kirigami.Units.gridUnit * 5)
Layout.maximumHeight: Kirigami.Units.gridUnit * 5
Layout.fillWidth: true
Layout.preferredHeight: replyLabel.height + replyItem.height + Kirigami.Units.largeSpacing
ColumnLayout {
anchors.fill: parent
spacing: 0
Label {
id: replyLabel
Layout.leftMargin: Kirigami.Units.largeSpacing
Layout.topMargin: Kirigami.Units.largeSpacing
Layout.fillWidth: true
text: l10n.get('send-message-box-reply-to')
}
<<<<<<< HEAD
Item {
id: replyItem
Layout.leftMargin: Kirigami.Units.largeSpacing
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.draftReplyTo)
compactMode: true
}
}
}
}
ToolButton {
Layout.alignment: Qt.AlignTop
Layout.rightMargin: Kirigami.Units.largeSpacing
action: removeReplyToAction
display: AbstractButton.IconOnly
=======
Kazv.EventViewWrapper {
id: replyToEventView
anchors {
top: parent.top
left: parent.left
right: parent.right
}
event: room.messageById(sendMessageBox.draftRelatedTo)
compactMode: true
>>>>>>> efb9f3995c92e1714caf1149be92210ef43d8b85
}
}
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()
Layout.fillWidth: true
wrapMode: TextEdit.Wrap
onTextChanged: {
room.setLocalDraft(text);
if (!inhibitTyping) {
room.setTyping(true);
}
inhibitTyping = false;
}
function changeText(newText, inhibitTyping) {
textArea.inhibitTyping = inhibitTyping;
textArea.text = newText;
}
onVisibleChanged: {
if (!visible) {
room.updateLocalDraftNow();
}
}
function getFilter() {
const atPos = text.lastIndexOf('@', cursorPosition);
if (atPos < 0) {
return '';
}
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;
}
onFilterChanged: {
sendMessageBox.members.filter = filter.slice(1);
if (filter && sendMessageBox.members.count > 0) {
completionPopup.open();
} else {
completionPopup.close();
}
}
// Shortcut keys for sending messages (TODO: Shortcut keys customized by the user)
Shortcut {
sequences: textArea.shortcutList
onActivated: {
sendAction.trigger()
}
}
DropArea {
anchors.fill: parent
onDropped: (drag) => {
if (drag.hasUrls) {
confirmUploadPopup.call(drag.urls);
}
}
}
}
ToolButton {
action: sendMediaFileAction
display: AbstractButton.IconOnly
}
ToolButton {
action: stickersAction
display: AbstractButton.IconOnly
}
ToolButton {
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 = '';
}
}
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 {
onAccepted: {
sendMessageBox.uploadFile(fileUrl);
}
}
function uploadFile(fileUrl) {
kazvIOManager.startNewUploadJob(
matrixSdk.serverUrl, fileUrl, matrixSdk.token,
room.roomId, sdkVars.roomList, room.encrypted
);
}
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/plain
Expires
Sat, Nov 23, 10:11 PM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39158
Default Alt Text
SendMessageBox.qml (8 KB)

Event Timeline