mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 03:18:07 +00:00
fix get size with screen ratio function fix chat sending area ui #LINQT-2068 print debug logs in linphone files for futur debugging fix call history details ui when no video conference factory set use remote name of each call if in local conference #LINQT-2058
324 lines
No EOL
9.3 KiB
QML
324 lines
No EOL
9.3 KiB
QML
import QtQuick
|
|
import QtQuick.Controls.Basic as Control
|
|
import QtQuick.Dialogs
|
|
import QtQuick.Layouts
|
|
import Linphone
|
|
import UtilsCpp
|
|
|
|
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
|
|
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
|
|
|
|
Control.Control {
|
|
id: mainItem
|
|
|
|
// property alias placeholderText: sendingTextArea.placeholderText
|
|
property string text
|
|
property var textArea
|
|
property int selectedFilesCount: 0
|
|
// property alias cursorPosition: sendingTextArea.cursorPosition
|
|
|
|
property bool dropEnabled: true
|
|
property bool isEphemeral : false
|
|
property bool emojiVisible: false
|
|
|
|
// disable record button if call ongoing
|
|
property bool callOngoing: false
|
|
|
|
property ChatGui chat
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
signal dropped (var files)
|
|
signal validText (string text)
|
|
signal sendMessage()
|
|
signal emojiClicked()
|
|
signal composing()
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
function _emitFiles (files) {
|
|
// Filtering files, other urls are forbidden.
|
|
files = files.reduce(function (files, file) {
|
|
if (file.toString().startsWith("file:")) {
|
|
files.push(Utils.getSystemPathFromUri(file))
|
|
}
|
|
|
|
return files
|
|
}, [])
|
|
if (files.length > 0) {
|
|
dropped(files)
|
|
}
|
|
}
|
|
|
|
FileDialog {
|
|
id: fileDialog
|
|
fileMode: FileDialog.OpenFiles
|
|
onAccepted: _emitFiles(fileDialog.selectedFiles)
|
|
}
|
|
|
|
// width: mainItem.implicitWidth
|
|
// height: mainItem.height
|
|
leftPadding: Math.round(15 * DefaultStyle.dp)
|
|
rightPadding: Math.round(15 * DefaultStyle.dp)
|
|
topPadding: Math.round(16 * DefaultStyle.dp)
|
|
bottomPadding: Math.round(16 * DefaultStyle.dp)
|
|
background: Rectangle {
|
|
anchors.fill: parent
|
|
color: DefaultStyle.grey_100
|
|
}
|
|
contentItem: Control.StackView {
|
|
id: sendingAreaStackView
|
|
initialItem: textAreaComp
|
|
onHeightChanged: {
|
|
mainItem.height = height + mainItem.topPadding + mainItem.bottomPadding
|
|
}
|
|
Component {
|
|
id: textAreaComp
|
|
RowLayout {
|
|
spacing: Math.round(16 * DefaultStyle.dp)
|
|
PopupButton {
|
|
id: emojiPickerButton
|
|
style: ButtonStyle.noBackground
|
|
icon.source: checked ? AppIcons.closeX : AppIcons.smiley
|
|
popup.width: Math.round(393 * DefaultStyle.dp)
|
|
popup.height: Math.round(291 * DefaultStyle.dp)
|
|
popup.contentItem: EmojiPicker {
|
|
editor: sendingTextArea
|
|
}
|
|
}
|
|
BigButton {
|
|
style: ButtonStyle.noBackground
|
|
icon.source: AppIcons.paperclip
|
|
onClicked: {
|
|
fileDialog.open()
|
|
}
|
|
}
|
|
Control.Control {
|
|
id: sendingControl
|
|
onHeightChanged: {
|
|
sendingAreaStackView.height = height
|
|
}
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignCenter
|
|
leftPadding: Math.round(24 * DefaultStyle.dp)
|
|
rightPadding: Math.round(20 * DefaultStyle.dp)
|
|
topPadding: Math.round(12 * DefaultStyle.dp)
|
|
bottomPadding: Math.round(12 * DefaultStyle.dp)
|
|
background: Rectangle {
|
|
id: inputBackground
|
|
anchors.fill: parent
|
|
radius: Math.round(35 * DefaultStyle.dp)
|
|
color: DefaultStyle.grey_0
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onPressed: sendingTextArea.forceActiveFocus()
|
|
cursorShape: Qt.IBeamCursor
|
|
}
|
|
}
|
|
contentItem: RowLayout {
|
|
Flickable {
|
|
id: sendingAreaFlickable
|
|
Layout.preferredHeight: Math.min(Math.round(100 * DefaultStyle.dp), contentHeight)
|
|
Layout.fillHeight: true
|
|
width: sendingControl.width - sendingControl.leftPadding - sendingControl.rightPadding
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignCenter
|
|
contentHeight: sendingTextArea.contentHeight
|
|
contentWidth: width
|
|
|
|
function ensureVisible(r) {
|
|
if (contentX >= r.x)
|
|
contentX = r.x;
|
|
else if (contentX+width <= r.x+r.width)
|
|
contentX = r.x+r.width-width;
|
|
if (contentY >= r.y)
|
|
contentY = r.y;
|
|
else if (contentY+height <= r.y+r.height)
|
|
contentY = r.y+r.height-height;
|
|
}
|
|
|
|
TextArea {
|
|
id: sendingTextArea
|
|
// RectangleTest{anchors.fill: parent}
|
|
width: sendingAreaFlickable.width
|
|
height: implicitHeight// sendingAreaFlickable.height
|
|
textFormat: TextEdit.AutoText
|
|
onTextChanged: {
|
|
mainItem.text = text
|
|
}
|
|
Component.onCompleted: {
|
|
mainItem.textArea = sendingTextArea
|
|
sendingTextArea.text = mainItem.text
|
|
}
|
|
//: Say something… : placeholder text for sending message text area
|
|
placeholderText: qsTr("chat_view_send_area_placeholder_text")
|
|
placeholderTextColor: DefaultStyle.main2_400
|
|
color: DefaultStyle.main2_700
|
|
font {
|
|
pixelSize: Typography.p1.pixelSize
|
|
weight: Typography.p1.weight
|
|
}
|
|
onCursorRectangleChanged: sendingAreaFlickable.ensureVisible(cursorRectangle)
|
|
wrapMode: TextEdit.WordWrap
|
|
KeyNavigation.tab: recordButton.visible ? recordButton : sendMessageButton
|
|
Keys.onPressed: (event) => {
|
|
if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return))
|
|
if(!(event.modifiers & Qt.ShiftModifier)) {
|
|
mainItem.sendMessage()
|
|
event.accepted = true
|
|
}
|
|
}
|
|
Connections {
|
|
target: mainItem
|
|
function onTextChanged() {
|
|
sendingTextArea.text = mainItem.text
|
|
}
|
|
function onSendMessage() {
|
|
sendingTextArea.clear()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
RowLayout {
|
|
id: stackButton
|
|
spacing: 0
|
|
Layout.preferredHeight: Math.max(recordButton.height, sendMessageButton.height)
|
|
BigButton {
|
|
id: recordButton
|
|
ToolTip.visible: !enabled && hovered
|
|
//: Cannot record a message while a call is ongoing
|
|
ToolTip.text: qsTr("cannot_record_while_in_call_tooltip")
|
|
enabled: !mainItem.callOngoing
|
|
visible: !mainItem.callOngoing && sendingTextArea.text.length === 0 && mainItem.selectedFilesCount === 0
|
|
style: ButtonStyle.noBackground
|
|
hoverEnabled: true
|
|
icon.source: AppIcons.microphone
|
|
onClicked: {
|
|
sendingAreaStackView.push(voiceMessageRecordComp)
|
|
}
|
|
}
|
|
BigButton {
|
|
id: sendMessageButton
|
|
Layout.preferredHeight: height
|
|
visible: sendingTextArea.text.length !== 0 || mainItem.selectedFilesCount > 0
|
|
style: ButtonStyle.noBackgroundOrange
|
|
icon.source: AppIcons.paperPlaneRight
|
|
onClicked: {
|
|
mainItem.sendMessage()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Component {
|
|
id: voiceMessageRecordComp
|
|
RowLayout {
|
|
spacing: Math.round(16 * DefaultStyle.dp)
|
|
RoundButton {
|
|
style: ButtonStyle.player
|
|
shadowEnabled: true
|
|
padding: Math.round(4 * DefaultStyle.dp)
|
|
icon.width: Math.round(22 * DefaultStyle.dp)
|
|
icon.height: Math.round(22 * DefaultStyle.dp)
|
|
icon.source: AppIcons.closeX
|
|
width: Math.round(30 * DefaultStyle.dp)
|
|
Layout.preferredWidth: width
|
|
Layout.preferredHeight: height
|
|
onClicked: {
|
|
if (voiceMessage.chatMessage) mainItem.chat.core.lDeleteMessage(voiceMessage.chatMessage)
|
|
sendingAreaStackView.pop()
|
|
}
|
|
}
|
|
ChatAudioContent {
|
|
id: voiceMessage
|
|
onHeightChanged: {
|
|
sendingAreaStackView.height = height
|
|
}
|
|
recording: true
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: Math.round(48 * DefaultStyle.dp)
|
|
chatMessageContentGui: chatMessage ? chatMessage.core.getVoiceRecordingContent() : null
|
|
onVoiceRecordingMessageCreationRequested: (recorderGui) => {
|
|
chatMessageObj = UtilsCpp.createVoiceRecordingMessage(recorderGui, mainItem.chat)
|
|
}
|
|
}
|
|
BigButton {
|
|
id: sendButton
|
|
style: ButtonStyle.noBackgroundOrange
|
|
icon.source: AppIcons.paperPlaneRight
|
|
icon.width: Math.round(22 * DefaultStyle.dp)
|
|
icon.height: Math.round(22 * DefaultStyle.dp)
|
|
// Layout.preferredWidth: icon.width
|
|
// Layout.preferredHeight: icon.height
|
|
property bool sendVoiceRecordingOnCreated: false
|
|
onClicked: {
|
|
if (voiceMessage.chatMessage) {
|
|
voiceMessage.chatMessage.core.lSend()
|
|
sendingAreaStackView.pop()
|
|
}
|
|
else {
|
|
sendVoiceRecordingOnCreated = true
|
|
voiceMessage.stopRecording()
|
|
}
|
|
}
|
|
Connections {
|
|
target: voiceMessage
|
|
function onChatMessageChanged() {
|
|
if (sendButton.sendVoiceRecordingOnCreated) {
|
|
voiceMessage.chatMessage.core.lSend()
|
|
sendButton.sendVoiceRecordingOnCreated = false
|
|
sendingAreaStackView.pop()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
id: hoverContent
|
|
anchors.fill: parent
|
|
color: DefaultStyle.main2_0
|
|
visible: false
|
|
radius: Math.round(20 * DefaultStyle.dp)
|
|
|
|
EffectImage {
|
|
anchors.centerIn: parent
|
|
imageSource: AppIcons.filePlus
|
|
width: Math.round(37 * DefaultStyle.dp)
|
|
height: Math.round(37 * DefaultStyle.dp)
|
|
colorizationColor: DefaultStyle.main2_500_main
|
|
}
|
|
|
|
DashRectangle {
|
|
x: parent.x
|
|
y: parent.y
|
|
radius: hoverContent.radius
|
|
color: DefaultStyle.main2_500_main
|
|
width: parent.width
|
|
height: parent.height
|
|
}
|
|
}
|
|
DropArea {
|
|
anchors.fill: parent
|
|
keys: [ 'text/uri-list' ]
|
|
visible: mainItem.dropEnabled
|
|
|
|
onDropped: (drop) => {
|
|
state = ''
|
|
if (drop.hasUrls) {
|
|
_emitFiles(drop.urls)
|
|
}
|
|
}
|
|
onEntered: state = 'hover'
|
|
onExited: state = ''
|
|
|
|
states: State {
|
|
name: 'hover'
|
|
PropertyChanges { target: hoverContent; visible: true }
|
|
}
|
|
}
|
|
} |