moment/src/qml/Chat/SendBox.qml

129 lines
4.0 KiB
QML
Raw Normal View History

2019-07-08 13:52:41 +10:00
// Copyright 2019 miruka
// This file is part of harmonyqml, licensed under LGPLv3.
import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../Base"
2019-03-22 14:28:14 +11:00
HRectangle {
function setFocus() { areaScrollView.forceActiveFocus() }
2019-03-22 14:28:14 +11:00
property var aliases: window.settings.write_aliases
property string writingUserId: chatPage.userId
property string toSend: ""
property bool textChangedSinceLostFocus: false
property alias textArea: areaScrollView.area
2019-07-07 07:56:04 +10:00
id: sendBox
2019-03-22 14:28:14 +11:00
Layout.fillWidth: true
Layout.minimumHeight: theme.baseElementsHeight
Layout.preferredHeight: areaScrollView.implicitHeight
2019-03-22 14:28:14 +11:00
// parent.height / 2 causes binding loop?
Layout.maximumHeight: pageStack.height / 2
color: theme.chat.sendBox.background
2019-03-22 14:28:14 +11:00
HRowLayout {
2019-03-22 14:28:14 +11:00
anchors.fill: parent
HUserAvatar {
id: avatar
userId: writingUserId
2019-03-22 14:28:14 +11:00
}
HScrollableTextArea {
2019-03-22 14:28:14 +11:00
Layout.fillHeight: true
Layout.fillWidth: true
2019-07-07 07:56:04 +10:00
Layout.topMargin: Math.max(0, sendBox.Layout.minimumHeight - 34)
2019-03-22 14:28:14 +11:00
id: areaScrollView
placeholderText: qsTr("Type a message...")
2019-04-29 05:13:18 +10:00
backgroundColor: "transparent"
area.focus: true
function setTyping(typing) {
2019-07-08 13:28:10 +10:00
py.callClientCoro(
writingUserId,
2019-07-08 13:28:10 +10:00
"room_typing",
[chatPage.roomId, typing, 5000]
)
}
onTextChanged: {
let foundAlias = null
for (let [user, writing_alias] of Object.entries(aliases)) {
if (text.startsWith(writing_alias + " ")) {
writingUserId = user
foundAlias = new RegExp("^" + writing_alias + " ")
break
}
}
if (foundAlias) {
toSend = text.replace(foundAlias, "")
setTyping(Boolean(text))
textChangedSinceLostFocus = true
return
}
writingUserId = Qt.binding(() => chatPage.userId)
toSend = text
let vals = Object.values(aliases)
let longestAlias =
vals.reduce((a, b) => a.length > b.length ? a: b)
let textNotStartsWithAnyAlias =
! vals.some(a => text.startsWith(a))
let textContainsCharNotInAnyAlias =
vals.every(a => text.split("").some(c => ! a.includes(c)))
// Only set typing when it's sure that the user will not use
// an alias and has written something
if (toSend &&
(text.length > longestAlias.length ||
textNotStartsWithAnyAlias ||
textContainsCharNotInAnyAlias))
{
setTyping(Boolean(text))
textChangedSinceLostFocus = true
}
}
area.onEditingFinished: { // when lost focus
if (text && textChangedSinceLostFocus) {
setTyping(false)
textChangedSinceLostFocus = false
}
}
2019-03-22 14:28:14 +11:00
Component.onCompleted: {
area.Keys.onReturnPressed.connect(event => {
event.accepted = true
2019-03-22 14:28:14 +11:00
if (event.modifiers & Qt.ShiftModifier ||
event.modifiers & Qt.ControlModifier ||
event.modifiers & Qt.AltModifier)
{
textArea.insert(textArea.cursorPosition, "\n")
return
}
if (textArea.text === "") { return }
2019-07-04 11:20:49 +10:00
let args = [chatPage.roomId, toSend]
py.callClientCoro(writingUserId, "send_markdown", args)
area.clear()
})
area.Keys.onEnterPressed.connect(area.Keys.onReturnPressed)
}
2019-03-22 14:28:14 +11:00
}
}
}