Cap height of send message box, and make it scrollable
This commit is contained in:
@@ -284,173 +284,177 @@ ToolBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TextArea {
|
ScrollView {
|
||||||
id: inputField
|
|
||||||
property real progress: 0
|
|
||||||
property bool autoAppeared: false
|
|
||||||
|
|
||||||
ChatDocumentHandler {
|
|
||||||
id: documentHandler
|
|
||||||
document: inputField.textDocument
|
|
||||||
cursorPosition: inputField.cursorPosition
|
|
||||||
selectionStart: inputField.selectionStart
|
|
||||||
selectionEnd: inputField.selectionEnd
|
|
||||||
room: currentRoom ?? null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.maximumHeight: inputField.lineHeight * 8
|
||||||
|
TextArea {
|
||||||
|
id: inputField
|
||||||
|
property real progress: 0
|
||||||
|
property bool autoAppeared: false
|
||||||
|
|
||||||
wrapMode: Text.Wrap
|
ChatDocumentHandler {
|
||||||
placeholderText: i18n("Write your message...")
|
id: documentHandler
|
||||||
topPadding: 0
|
document: inputField.textDocument
|
||||||
bottomPadding: 0
|
cursorPosition: inputField.cursorPosition
|
||||||
leftPadding: Kirigami.Units.smallSpacing
|
selectionStart: inputField.selectionStart
|
||||||
selectByMouse: true
|
selectionEnd: inputField.selectionEnd
|
||||||
verticalAlignment: TextEdit.AlignVCenter
|
room: currentRoom ?? null
|
||||||
|
|
||||||
text: currentRoom != null ? currentRoom.cachedInput : ""
|
|
||||||
|
|
||||||
background: Item {}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: currentRoom && currentRoom.hasFileUploading ? parent.width * currentRoom.fileUploadingProgress / 100 : 0
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
opacity: 0.2
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: timeoutTimer
|
|
||||||
|
|
||||||
repeat: false
|
|
||||||
interval: 2000
|
|
||||||
onTriggered: {
|
|
||||||
repeatTimer.stop()
|
|
||||||
currentRoom.sendTypingNotification(false)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: repeatTimer
|
|
||||||
|
|
||||||
repeat: true
|
property int lineHeight: contentHeight / lineCount
|
||||||
interval: 5000
|
|
||||||
triggeredOnStart: true
|
wrapMode: Text.Wrap
|
||||||
onTriggered: currentRoom.sendTypingNotification(true)
|
placeholderText: i18n("Write your message...")
|
||||||
}
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
leftPadding: Kirigami.Units.smallSpacing
|
||||||
|
selectByMouse: true
|
||||||
|
verticalAlignment: TextEdit.AlignVCenter
|
||||||
|
|
||||||
|
text: currentRoom != null ? currentRoom.cachedInput : ""
|
||||||
|
|
||||||
|
background: Item {}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: currentRoom && currentRoom.hasFileUploading ? parent.width * currentRoom.fileUploadingProgress / 100 : 0
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
opacity: 0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: timeoutTimer
|
||||||
|
|
||||||
|
repeat: false
|
||||||
|
interval: 2000
|
||||||
|
onTriggered: {
|
||||||
|
repeatTimer.stop()
|
||||||
|
currentRoom.sendTypingNotification(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: repeatTimer
|
||||||
|
|
||||||
|
repeat: true
|
||||||
|
interval: 5000
|
||||||
|
triggeredOnStart: true
|
||||||
|
onTriggered: currentRoom.sendTypingNotification(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
if (isAutoCompleting) {
|
||||||
|
inputField.autoComplete();
|
||||||
|
|
||||||
|
isAutoCompleting = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.modifiers & Qt.ShiftModifier) {
|
||||||
|
insert(cursorPosition, "\n")
|
||||||
|
} else {
|
||||||
|
postMessage()
|
||||||
|
text = ""
|
||||||
|
clearReply()
|
||||||
|
closeAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onEscapePressed: closeAll()
|
||||||
|
|
||||||
|
Keys.onPressed: {
|
||||||
|
if (event.key === Qt.Key_PageDown) {
|
||||||
|
switchRoomDown();
|
||||||
|
} else if (event.key === Qt.Key_PageUp) {
|
||||||
|
switchRoomUp();
|
||||||
|
} else if (event.key === Qt.Key_V && event.modifiers & Qt.ControlModifier) {
|
||||||
|
root.pasteImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onBacktabPressed: {
|
||||||
|
if (event.modifiers & Qt.ControlModifier) {
|
||||||
|
switchRoomUp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isAutoCompleting) {
|
||||||
|
autoCompleteListView.decrementCurrentIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (event.modifiers & Qt.ControlModifier) {
|
||||||
|
switchRoomDown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isAutoCompleting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO detect moved cursor
|
||||||
|
|
||||||
|
// ignore first time tab was clicked so that user can select
|
||||||
|
// first emoji/user
|
||||||
|
if (autoAppeared === false) {
|
||||||
|
autoCompleteListView.incrementCurrentIndex()
|
||||||
|
} else {
|
||||||
|
autoAppeared = false;
|
||||||
|
}
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
|
||||||
if (isAutoCompleting) {
|
|
||||||
inputField.autoComplete();
|
inputField.autoComplete();
|
||||||
|
|
||||||
isAutoCompleting = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.modifiers & Qt.ShiftModifier) {
|
|
||||||
insert(cursorPosition, "\n")
|
|
||||||
} else {
|
|
||||||
postMessage()
|
|
||||||
text = ""
|
|
||||||
clearReply()
|
|
||||||
closeAll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onEscapePressed: closeAll()
|
|
||||||
|
|
||||||
Keys.onPressed: {
|
|
||||||
if (event.key === Qt.Key_PageDown) {
|
|
||||||
switchRoomDown();
|
|
||||||
} else if (event.key === Qt.Key_PageUp) {
|
|
||||||
switchRoomUp();
|
|
||||||
} else if (event.key === Qt.Key_V && event.modifiers & Qt.ControlModifier) {
|
|
||||||
root.pasteImage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onBacktabPressed: {
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
switchRoomUp();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isAutoCompleting) {
|
|
||||||
autoCompleteListView.decrementCurrentIndex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onTabPressed: {
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
switchRoomDown();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!isAutoCompleting) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO detect moved cursor
|
onTextChanged: {
|
||||||
|
timeoutTimer.restart()
|
||||||
// ignore first time tab was clicked so that user can select
|
repeatTimer.start()
|
||||||
// first emoji/user
|
currentRoom.cachedInput = text
|
||||||
if (autoAppeared === false) {
|
|
||||||
autoCompleteListView.incrementCurrentIndex()
|
|
||||||
} else {
|
|
||||||
autoAppeared = false;
|
autoAppeared = false;
|
||||||
|
|
||||||
|
const autocompletionInfo = documentHandler.getAutocompletionInfo();
|
||||||
|
|
||||||
|
if (autocompletionInfo.type === ChatDocumentHandler.Ignore) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (autocompletionInfo.type === ChatDocumentHandler.None) {
|
||||||
|
isAutoCompleting = false;
|
||||||
|
autoCompleteListView.currentIndex = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (autocompletionInfo.type === ChatDocumentHandler.User) {
|
||||||
|
autoCompleteModel = currentRoom.getUsers(autocompletionInfo.keyword);
|
||||||
|
} else {
|
||||||
|
autoCompleteModel = emojiModel.filterModel(autocompletionInfo.keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (autoCompleteModel.length === 0) {
|
||||||
|
isAutoCompleting = false;
|
||||||
|
autoCompleteListView.currentIndex = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isAutoCompleting = true
|
||||||
|
autoAppeared = true;
|
||||||
|
autoCompleteEndPosition = cursorPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
inputField.autoComplete();
|
function postMessage() {
|
||||||
}
|
// Qt wraps lines so we need to use a small hack
|
||||||
|
// to remove the wrapped lines but not break the empty
|
||||||
onTextChanged: {
|
// lines.
|
||||||
timeoutTimer.restart()
|
const updatedText = inputField.text.trim()
|
||||||
repeatTimer.start()
|
.replace(/@([^: ]*):([^ ]*\.[^ ]*)/, "[@$1:$2](https://matrix.to/#/@$1:$2)");
|
||||||
currentRoom.cachedInput = text
|
documentHandler.postMessage(updatedText, attachmentPath, replyEventID);
|
||||||
autoAppeared = false;
|
clearAttachment();
|
||||||
|
currentRoom.markAllMessagesAsRead();
|
||||||
const autocompletionInfo = documentHandler.getAutocompletionInfo();
|
clear();
|
||||||
|
text = Qt.binding(function() {
|
||||||
if (autocompletionInfo.type === ChatDocumentHandler.Ignore) {
|
return currentRoom != null ? currentRoom.cachedInput : "";
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
if (autocompletionInfo.type === ChatDocumentHandler.None) {
|
|
||||||
isAutoCompleting = false;
|
|
||||||
autoCompleteListView.currentIndex = 0;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (autocompletionInfo.type === ChatDocumentHandler.User) {
|
function autoComplete() {
|
||||||
autoCompleteModel = currentRoom.getUsers(autocompletionInfo.keyword);
|
documentHandler.replaceAutoComplete(autoCompleteListView.currentItem.displayText)
|
||||||
} else {
|
|
||||||
autoCompleteModel = emojiModel.filterModel(autocompletionInfo.keyword);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (autoCompleteModel.length === 0) {
|
|
||||||
isAutoCompleting = false;
|
|
||||||
autoCompleteListView.currentIndex = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
isAutoCompleting = true
|
|
||||||
autoAppeared = true;
|
|
||||||
autoCompleteEndPosition = cursorPosition
|
|
||||||
}
|
|
||||||
|
|
||||||
function postMessage() {
|
|
||||||
// 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(/@([^: ]*):([^ ]*\.[^ ]*)/, "[@$1:$2](https://matrix.to/#/@$1:$2)");
|
|
||||||
documentHandler.postMessage(updatedText, attachmentPath, replyEventID);
|
|
||||||
clearAttachment();
|
|
||||||
currentRoom.markAllMessagesAsRead();
|
|
||||||
clear();
|
|
||||||
text = Qt.binding(function() {
|
|
||||||
return currentRoom != null ? currentRoom.cachedInput : "";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function autoComplete() {
|
|
||||||
documentHandler.replaceAutoComplete(autoCompleteListView.currentItem.displayText)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user