when the user sends a new message, and if the user is at an older position in the timeline, then neochat should automatically scroll to the latest message and mark all the messages as read
227 lines
6.4 KiB
QML
227 lines
6.4 KiB
QML
/* SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.de>
|
|
* SPDX-FileCopyrightText: 2020 Noah Davis <noahadvs@gmail.com>
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
import QtQuick 2.15
|
|
import Qt.labs.platform 1.0 as Platform
|
|
import org.kde.kirigami 2.14 as Kirigami
|
|
|
|
import NeoChat.Component.ChatBox 1.0
|
|
import NeoChat.Component.Emoji 1.0
|
|
import org.kde.neochat 1.0
|
|
|
|
Item {
|
|
id: root
|
|
property alias inputFieldText: chatBar.inputFieldText
|
|
|
|
signal fancyEffectsReasonFound(string fancyEffect)
|
|
signal messageSent()
|
|
|
|
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
|
|
|
implicitWidth: {
|
|
let w = 0
|
|
for(let i = 0; i < visibleChildren.length; ++i) {
|
|
w = Math.max(w, Math.ceil(visibleChildren[i].implicitWidth))
|
|
}
|
|
return w
|
|
}
|
|
implicitHeight: {
|
|
let h = 0
|
|
for(let i = 0; i < visibleChildren.length; ++i) {
|
|
h += Math.ceil(visibleChildren[i].implicitHeight)
|
|
}
|
|
return h
|
|
}
|
|
|
|
// For some reason, this is needed to make the height animation work even though
|
|
// it used to work and height should be directly affected by implicitHeight
|
|
height: implicitHeight
|
|
|
|
Behavior on height {
|
|
NumberAnimation {
|
|
property: "height"
|
|
duration: Kirigami.Units.shortDuration
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
|
|
Kirigami.Separator {
|
|
id: emojiPickerLoaderSeparator
|
|
visible: emojiPickerLoader.visible
|
|
width: parent.width
|
|
height: visible ? implicitHeight : 0
|
|
anchors.bottom: emojiPickerLoader.top
|
|
z: 1
|
|
}
|
|
|
|
Loader {
|
|
id: emojiPickerLoader
|
|
active: visible
|
|
visible: chatBar.emojiPaneOpened
|
|
width: parent.width
|
|
height: visible ? implicitHeight : 0
|
|
anchors.bottom: replySeparator.top
|
|
sourceComponent: EmojiPicker{
|
|
textArea: chatBar.textField
|
|
onChosen: addText(emoji)
|
|
}
|
|
Behavior on height {
|
|
NumberAnimation {
|
|
property: "height"
|
|
duration: Kirigami.Units.shortDuration
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Kirigami.Separator {
|
|
id: replySeparator
|
|
visible: replyPane.visible
|
|
width: parent.width
|
|
height: visible ? implicitHeight : 0
|
|
anchors.bottom: replyPane.top
|
|
}
|
|
|
|
ReplyPane {
|
|
id: replyPane
|
|
visible: ChatBoxHelper.isReplying || ChatBoxHelper.isEditing
|
|
user: ChatBoxHelper.replyUser
|
|
width: parent.width
|
|
height: visible ? implicitHeight : 0
|
|
anchors.bottom: attachmentSeparator.top
|
|
Behavior on height {
|
|
NumberAnimation {
|
|
property: "height"
|
|
duration: Kirigami.Units.shortDuration
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
}
|
|
|
|
Kirigami.Separator {
|
|
id: attachmentSeparator
|
|
visible: attachmentPane.visible
|
|
width: parent.width
|
|
height: visible ? implicitHeight : 0
|
|
anchors.bottom: attachmentPane.top
|
|
}
|
|
|
|
AttachmentPane {
|
|
id: attachmentPane
|
|
visible: ChatBoxHelper.hasAttachment
|
|
width: parent.width
|
|
height: visible ? implicitHeight : 0
|
|
anchors.bottom: chatBarSeparator.top
|
|
Behavior on height {
|
|
NumberAnimation {
|
|
property: "height"
|
|
duration: Kirigami.Units.shortDuration
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
}
|
|
|
|
Kirigami.Separator {
|
|
id: chatBarSeparator
|
|
visible: chatBar.visible
|
|
width: parent.width
|
|
height: visible ? implicitHeight : 0
|
|
anchors.bottom: chatBar.top
|
|
}
|
|
|
|
ChatBar {
|
|
id: chatBar
|
|
visible: currentRoom.canSendEvent("m.room.message")
|
|
width: parent.width
|
|
height: visible ? implicitHeight : 0
|
|
anchors.bottom: parent.bottom
|
|
|
|
Behavior on height {
|
|
NumberAnimation {
|
|
property: "height"
|
|
duration: Kirigami.Units.shortDuration
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
|
|
onCloseAllTriggered: closeAll()
|
|
onMessageSent: {
|
|
closeAll()
|
|
checkForFancyEffectsReason()
|
|
root.messageSent();
|
|
}
|
|
}
|
|
|
|
function checkForFancyEffectsReason() {
|
|
if (!Config.showFancyEffects) {
|
|
return
|
|
}
|
|
|
|
let text = root.inputFieldText.trim()
|
|
if (text.includes('\u{2744}')) {
|
|
root.fancyEffectsReasonFound("snowflake")
|
|
}
|
|
if (text.includes('\u{1F386}')) {
|
|
root.fancyEffectsReasonFound("fireworks")
|
|
}
|
|
if (text.includes('\u{1F387}')) {
|
|
root.fancyEffectsReasonFound("fireworks")
|
|
}
|
|
if (text.includes('\u{1F389}')) {
|
|
root.fancyEffectsReasonFound("confetti")
|
|
}
|
|
if (text.includes('\u{1F38A}')) {
|
|
root.fancyEffectsReasonFound("confetti")
|
|
}
|
|
}
|
|
|
|
function addText(text) {
|
|
root.inputFieldText = inputFieldText + text
|
|
}
|
|
|
|
function insertText(str) {
|
|
root.inputFieldText = inputFieldText.substr(0, inputField.cursorPosition) + str + inputFieldText.substr(inputField.cursorPosition)
|
|
}
|
|
|
|
function focusInputField() {
|
|
chatBar.inputFieldForceActiveFocusTriggered()
|
|
}
|
|
|
|
Connections {
|
|
target: ChatBoxHelper
|
|
|
|
function onShouldClearText() {
|
|
root.inputFieldText = "";
|
|
}
|
|
|
|
function onEditing(editContent, editFormatedContent) {
|
|
// Set the input field in edit mode
|
|
root.inputFieldText = editContent;
|
|
//root.replyContent = editContent;
|
|
|
|
// clean autocompletion list
|
|
chatBar.userAutocompleted = {};
|
|
|
|
// Fill autocompletion list with values extracted from message.
|
|
// We can't just iterate on every user in the list and try to
|
|
// find matching display name since some users have display name
|
|
// matching frequent words and this will marks too many words as
|
|
// mentions.
|
|
const regex = /<a href=\"https:\/\/matrix.to\/#\/(@[a-zA-Z09]*:[a-zA-Z09.]*)\">([^<]*)<\/a>/g;
|
|
|
|
let match;
|
|
while ((match = regex.exec(editFormatedContent.toString())) !== null) {
|
|
chatBar.userAutocompleted[match[2]] = match[1];
|
|
}
|
|
}
|
|
}
|
|
|
|
function closeAll() {
|
|
ChatBoxHelper.clear();
|
|
chatBar.emojiPaneOpened = false;
|
|
}
|
|
}
|