import QtGraphicalEffects 1.0 import QtQuick 2.7 import QtQuick.Controls 2.4 import QtQuick.Controls.Material 2.0 import QtQuick.Layouts 1.3 import "../opaque" as Opaque import "../opaque/controls" as Awesome import "../utils.js" as Utils import "../widgets" import "../opaque/theme" import "../const" import "../opaque/fonts" ColumnLayout { id: root property int state: Const.state_disconnected property string authorization: "" signal sendClicked(string messageText) function updateState() { // TODO unapproved if (root.authorization == Const.auth_blocked) { statusSeperator.color = Theme.messageStatusBlockedColor //: Peer is blocked statusText.text = qsTr("peer-blocked-message") statusText.color = Theme.messageStatusBlockedTextColor txtMessage.enabled = false btnSend.enabled = false btnAttach.enabled = false btnEmoji.enabled = false } else if ( (Utils.isGroup(gcd.selectedConversation) && root.state == Const.state_synced) || (Utils.isPeer(gcd.selectedConversation) && root.state == Const.state_authenticated) ) { statusSeperator.color = Theme.messageStatusNormalColor statusText.text = "" txtMessage.enabled = true btnSend.enabled = true btnSend.enabled = true btnAttach.enabled = true btnEmoji.enabled = true } else { statusSeperator.color = Theme.messageStatusAlertColor //: Peer is offline, messages can't be delivered right now statusText.text = qsTr("peer-offline-message") statusText.color = Theme.messageStatusAlertTextColor txtMessage.enabled = false btnSend.enabled = false btnSend.enabled = false btnAttach.enabled = false btnEmoji.enabled = false } } Opaque.EmojiDrawer { id: emojiDrawer Layout.fillWidth: true size: 24 * gcd.themeScale onPicked: function(shortcode) { if (!txtMessage.enabled) return txtMessage.insert(txtMessage.cursorPosition, ":" + shortcode + ":") } } Rectangle { id: statusSeperator Layout.fillWidth: true height: statusText.visible ? statusText.height + (4 * gcd.themeScale) : 3 * gcd.themeScale implicitHeight: height color: Theme.dividerColor Opaque.ScalingLabel { id: statusText anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter width: parent.width - 2 * Theme.paddingMinimal horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight wrapMode: Text.NoWrap text: "" visible: text != "" size: Theme.chatMetaTextSize font.family: Fonts.applicationFontRegular.name font.styleName: "Bold" } } RowLayout { // THE BOTTOM DRAWER id: rowDrawer Layout.fillWidth: true Rectangle { // MESSAGE ENTRY TEXTFIELD id: rectMessage Layout.fillWidth: true Layout.minimumHeight: 120 * gcd.themeScale Layout.maximumHeight: 120 * gcd.themeScale color: Theme.backgroundMainColor Opaque.Flickable { id: flkMessage anchors.fill: parent //this does nothing! bug in qt contentWidth: txtMessage.width contentHeight: txtMessage.height + txtma.height TextArea { id: txtMessage font.pixelSize: Theme.chatSize * gcd.themeScale text: "" padding: 6 * gcd.themeScale wrapMode: TextEdit.Wrap textFormat: Text.PlainText width: rectMessage.width color: Theme.mainTextColor property bool skipOneUpdate: false property int previousCursor Keys.onReturnPressed: { if (gcd.os == "android") { txtMessage.insert(txtMessage.cursorPosition, "\n") } else if (event.modifiers & Qt.ShiftModifier) { txtMessage.insert(txtMessage.cursorPosition, "\n") } else if (event.modifiers == Qt.NoModifier) { btnSend.clicked() } } onTextChanged: { // autoscroll down only when the scrollbar is already all the way down if (flkMessage.contentY + flkMessage.height >= flkMessage.contentHeight - txtMessage.height && flkMessage.contentHeight > flkMessage.height) { flkMessage.contentY = flkMessage.contentHeight - flkMessage.height } } } MouseArea { id: txtma anchors.top: txtMessage.bottom width: flkMessage.width height: Math.max(rectMessage.height - txtMessage.height, 0) onClicked: { txtMessage.focus = true } } } } ColumnLayout { id: colRight spacing: 0 width: 100 * gcd.themeScale Layout.minimumWidth: width Layout.preferredWidth: width Layout.maximumWidth: width Opaque.Icon { // SEND MESSAGE BUTTON id: btnSend source: gcd.assetPath + "core/send-24px.webp" width: colRight.width // floor(...) needed or else send icon won't scale properly(?!?) height: Math.floor(50 * gcd.themeScale) size: 36 * gcd.themeScale sourceWidth: size sourceHeight: size backgroundColor: enabled ? Theme.defaultButtonColor : Theme.defaultButtonDisabledColor hilightBackgroundColor: Theme.defaultButtonActiveColor iconColor: Theme.defaultButtonTextColor property int nextMessageID: 1 onClicked: { var txt = txtMessage.text.trim() if (txt.length > 0) { root.sendClicked(txt) } txtMessage.text = "" } } RowLayout { Layout.alignment: Qt.AlignHCenter spacing: 0 Opaque.Icon { // EMOJI DRAWER BUTTON id: btnEmoji source: gcd.assetPath + "core/mood-24px.webp" size: 25 height: 36 * gcd.themeScale width: 48 * gcd.themeScale backgroundColor: enabled ? Theme.altButtonColor : Theme.altButtonDisabledColor hilightBackgroundColor: backgroundColor iconColor: enabled ? Theme.altButtonTextColor : Theme.altButtonDisabledTextColor onClicked: emojiDrawer.visible ? emojiDrawer.slideclosed() : emojiDrawer.slideopen() } Opaque.Icon { id: btnAttach source: gcd.assetPath + "core/attach_file-24px.webp" size: 25 height: 36 * gcd.themeScale width: 48 * gcd.themeScale backgroundColor: enabled ? Theme.altButtonColor : Theme.altButtonDisabledColor hilightBackgroundColor: backgroundColor iconColor: enabled ? Theme.altButtonTextColor : Theme.altButtonDisabledTextColor onClicked: { gcd.popup("attachments not yet implemented, sorry") } } } } } Connections { target: gcd onClearMessages: function() { txtMessage.text = "" } } }