mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-28 08:59:37 -05:00
9ba7b5cf47
Use proper Qml empty object notation instead of string to inistalize property of type var as it is an object not a string, thus fixing the assiciated warning
389 lines
8.3 KiB
QML
389 lines
8.3 KiB
QML
/*
|
|
* RetroShare Android QML App
|
|
* Copyright (C) 2016-2017 Gioacchino Mazzurco <gio@eigenlab.org>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import QtQuick 2.7
|
|
import QtQuick.Controls 2.0
|
|
import QtQuick.Layouts 1.2
|
|
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
|
import "." //Needed for TokensManager singleton
|
|
import "./components"
|
|
import "./components/emoji"
|
|
|
|
Item
|
|
{
|
|
id: chatView
|
|
property string chatId
|
|
property var gxsInfo: ({})
|
|
property int token: 0
|
|
|
|
property string objectName:"chatView"
|
|
|
|
|
|
function refreshData()
|
|
{
|
|
console.log("chatView.refreshData()", visible)
|
|
if(!visible) return
|
|
|
|
rsApi.request( "/chat/messages/"+chatId, "", function(par)
|
|
{
|
|
chatModel.json = par.response
|
|
token = JSON.parse(par.response).statetoken
|
|
TokensManager.registerToken(token, refreshData)
|
|
|
|
ChatCache.lastMessageCache.updateLastMessageCache(chatId, chatModel.json)
|
|
|
|
if(chatListView.visible)
|
|
{
|
|
chatListView.positionViewAtEnd()
|
|
rsApi.request("/chat/mark_chat_as_read/"+chatId)
|
|
}
|
|
})
|
|
}
|
|
|
|
Component.onCompleted:
|
|
{
|
|
refreshData()
|
|
}
|
|
onFocusChanged: focus && refreshData()
|
|
|
|
function changeState ()
|
|
{
|
|
toolBar.state = "CHATVIEW"
|
|
gxsInfo = ChatCache.lastMessageCache.getGxsFromChatId(chatView.chatId)
|
|
toolBar.gxsSource = gxsInfo.gxs
|
|
toolBar.titleText = gxsInfo.name
|
|
}
|
|
|
|
|
|
JSONListModel
|
|
{
|
|
id: chatModel
|
|
query: "$.data[*]"
|
|
}
|
|
|
|
ListView
|
|
{
|
|
property var styles: StyleChat.chat
|
|
id: chatListView
|
|
width: parent.width - styles.bubbleMargin
|
|
height: parent.height - inferiorPanel.height
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
model: chatModel.model
|
|
delegate: ChatBubbleDelegate {}
|
|
spacing: styles.bubbleSpacing
|
|
preferredHighlightBegin: 1
|
|
|
|
onHeightChanged:
|
|
{
|
|
chatListView.currentIndex = count - 1
|
|
}
|
|
|
|
}
|
|
|
|
EmojiPicker {
|
|
id: emojiPicker
|
|
|
|
anchors.fill: parent
|
|
anchors.topMargin: parent.height / 2
|
|
anchors.bottomMargin: if(!androidMode) categorySelectorHeight
|
|
|
|
property int categorySelectorHeight: 50
|
|
|
|
color: "white"
|
|
buttonWidth: 40
|
|
textArea: inferiorPanel.textMessageArea //the TextArea in which EmojiPicker is pasting the Emoji into
|
|
|
|
state: "EMOJI_HIDDEN"
|
|
states: [
|
|
State {
|
|
name: "EMOJI_HIDDEN"
|
|
PropertyChanges { target: emojiPicker; anchors.topMargin: parent.height }
|
|
PropertyChanges { target: emojiPicker; anchors.bottomMargin: -1 }
|
|
PropertyChanges { target: emojiPicker; height: 0 }
|
|
},
|
|
State {
|
|
name: "EMOJI_SHOWN"
|
|
PropertyChanges { target: emojiPicker; anchors.topMargin: parent.height / 2 }
|
|
PropertyChanges { target: emojiPicker; anchors.bottomMargin: categorySelectorHeight }
|
|
}
|
|
]
|
|
}
|
|
|
|
Item
|
|
{
|
|
|
|
property var styles: StyleChat.inferiorPanel
|
|
property alias textMessageArea: msgComposer.textMessageArea
|
|
|
|
id: inferiorPanel
|
|
height: ( msgComposer.height > styles.height)? msgComposer.height: styles.height
|
|
width: parent.width
|
|
anchors.bottom: emojiPicker.androidMode ? emojiPicker.top : parent.bottom
|
|
|
|
Rectangle
|
|
{
|
|
id: backgroundRectangle
|
|
anchors.fill: parent.fill
|
|
width: parent.width
|
|
height: parent.height
|
|
color:inferiorPanel.styles.backgroundColor
|
|
border.color: inferiorPanel.styles.borderColor
|
|
}
|
|
|
|
ButtonIcon
|
|
{
|
|
|
|
id: attachButton
|
|
|
|
property var styles: StyleChat.inferiorPanel.btnIcon
|
|
|
|
height: styles.height
|
|
width: styles.width
|
|
|
|
anchors.left: parent.left
|
|
anchors.bottom: parent.bottom
|
|
|
|
anchors.margins: styles.margin
|
|
|
|
imgUrl: styles.attachIconUrl
|
|
}
|
|
|
|
|
|
RowLayout
|
|
{
|
|
id: msgComposer
|
|
property var styles: StyleChat.inferiorPanel.msgComposer
|
|
property alias textMessageArea: flickable.msgField
|
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: attachButton.right
|
|
|
|
width: chatView.width -
|
|
(sendButton.width + sendButton.anchors.margins) -
|
|
(attachButton.width + attachButton.anchors.margins) -
|
|
(emojiButton.width + emojiButton.anchors.margins)
|
|
|
|
height: (flickable.contentHeight < styles.maxHeight)? flickable.contentHeight : styles.maxHeight
|
|
|
|
Flickable
|
|
{
|
|
id: flickable
|
|
property alias msgField: msgField
|
|
|
|
anchors.fill: parent
|
|
flickableDirection: Flickable.VerticalFlick
|
|
|
|
width: parent.width
|
|
|
|
contentWidth: msgField.width
|
|
contentHeight: msgField.height
|
|
contentY: contentHeight - height
|
|
|
|
ScrollBar.vertical: ScrollBar {}
|
|
|
|
clip: true
|
|
|
|
TextArea
|
|
{
|
|
property var styles: StyleChat.inferiorPanel.msgComposer
|
|
id: msgField
|
|
|
|
height: contentHeight + font.pixelSize
|
|
|
|
width: parent.width
|
|
|
|
placeholderText: styles.placeHolder
|
|
background: styles.background
|
|
|
|
wrapMode: TextEdit.Wrap
|
|
|
|
focus: true
|
|
|
|
inputMethodHints: Qt.ImhMultiLine
|
|
|
|
font.pixelSize: styles.messageBoxTextSize
|
|
|
|
onTextChanged:
|
|
{
|
|
var msgLenght = (msgField.preeditText)? msgField.preeditText.length : msgField.length
|
|
|
|
if (msgLenght == 0)
|
|
{
|
|
sendButton.state = ""
|
|
}
|
|
else if (msgLenght > 0 )
|
|
{
|
|
sendButton.state = "SENDBTN"
|
|
}
|
|
}
|
|
|
|
property bool shiftPressed: false
|
|
Keys.onPressed:
|
|
{
|
|
if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
|
|
&& !shiftPressed)
|
|
{
|
|
if (sendButton.state == "SENDBTN" )
|
|
{
|
|
chatView.sendMessage ()
|
|
}
|
|
}
|
|
else if (event.key === Qt.Key_Shift)
|
|
{
|
|
shiftPressed = true
|
|
}
|
|
}
|
|
|
|
Keys.onReleased:
|
|
{
|
|
if (event.key === Qt.Key_Shift)
|
|
{
|
|
shiftPressed = false
|
|
}
|
|
}
|
|
function reset ()
|
|
{
|
|
msgField.text = ""
|
|
Qt.inputMethod.reset()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ButtonIcon
|
|
{
|
|
|
|
id: emojiButton
|
|
|
|
property var styles: StyleChat.inferiorPanel.btnIcon
|
|
|
|
height: styles.height
|
|
width: styles.width
|
|
|
|
anchors.right: sendButton.left
|
|
anchors.bottom: parent.bottom
|
|
|
|
anchors.margins: styles.margin
|
|
|
|
imgUrl: styles.emojiIconUrl
|
|
|
|
onClicked: {
|
|
if (emojiPicker.state == "EMOJI_HIDDEN") {
|
|
emojiPicker.state = "EMOJI_SHOWN"
|
|
} else {
|
|
emojiPicker.state = "EMOJI_HIDDEN"
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
ButtonIcon
|
|
{
|
|
|
|
id: sendButton
|
|
|
|
property var styles: StyleChat.inferiorPanel.btnIcon
|
|
property alias icon: sendButton.imgUrl
|
|
|
|
height: styles.height
|
|
width: styles.width
|
|
|
|
anchors.right: parent.right
|
|
anchors.bottom: parent.bottom
|
|
|
|
anchors.margins: styles.margin
|
|
|
|
imgUrl: styles.microIconUrl
|
|
|
|
onClicked:
|
|
{
|
|
if (sendButton.state == "SENDBTN" )
|
|
{
|
|
chatView.sendMessage ()
|
|
}
|
|
}
|
|
|
|
onPressed:
|
|
{
|
|
if (sendButton.state == "RECORDING" )
|
|
{
|
|
sendButton.state = ""
|
|
}
|
|
else if (sendButton.state == "" )
|
|
{
|
|
sendButton.state = "RECORDING"
|
|
}
|
|
}
|
|
|
|
onReleased:
|
|
{
|
|
if (sendButton.state == "RECORDING" )
|
|
{
|
|
sendButton.state = ""
|
|
}
|
|
|
|
}
|
|
|
|
states:
|
|
[
|
|
State
|
|
{
|
|
name: ""
|
|
PropertyChanges { target: sendButton; icon: styles.microIconUrl}
|
|
},
|
|
State
|
|
{
|
|
name: "RECORDING"
|
|
PropertyChanges { target: sendButton; icon: styles.microMuteIconUrl}
|
|
},
|
|
State
|
|
{
|
|
name: "SENDBTN"
|
|
PropertyChanges { target: sendButton; icon: styles.sendIconUrl}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
function sendMessage ()
|
|
{
|
|
if (emojiPicker.state == "EMOJI_SHOWN") emojiPicker.state = "EMOJI_HIDDEN"
|
|
|
|
msgField.text = getCompleteMessageText () + " " // Needed to prevent pre edit text problems
|
|
var msgText = msgField.text
|
|
|
|
var jsonData = {"chat_id":chatView.chatId, "msg":msgText}
|
|
rsApi.request( "/chat/send_message", JSON.stringify(jsonData),
|
|
function(par)
|
|
{
|
|
msgField.reset();
|
|
})
|
|
}
|
|
|
|
// This function is needed for the compatibility with auto predictive keyboards
|
|
function getCompleteMessageText (){
|
|
var completeMsg
|
|
if (msgField.preeditText) completeMsg = msgField.text + msgField.preeditText
|
|
else completeMsg = msgField.text
|
|
return completeMsg
|
|
|
|
|
|
}
|
|
|
|
}
|