mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 03:18:07 +00:00
229 lines
No EOL
6.2 KiB
QML
229 lines
No EOL
6.2 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 alias text: sendingTextArea.text
|
|
property alias textArea: sendingTextArea
|
|
property alias cursorPosition: sendingTextArea.cursorPosition
|
|
property alias emojiPickerButtonChecked: emojiPickerButton.checked
|
|
|
|
property bool dropEnabled: true
|
|
property string dropDisabledReason
|
|
property bool isEphemeral : false
|
|
property bool emojiVisible: false
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
signal dropped (var files)
|
|
signal validText (string text)
|
|
signal sendText()
|
|
signal audioRecordRequest()
|
|
signal emojiClicked()
|
|
signal composing()
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
function _emitFiles (files) {
|
|
// Filtering files, other urls are forbidden.
|
|
files = files.reduce(function (files, file) {
|
|
console.log("dropping", file.toString())
|
|
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(24 * DefaultStyle.dp)
|
|
bottomPadding: Math.round(16 * DefaultStyle.dp)
|
|
background: Rectangle {
|
|
anchors.fill: parent
|
|
color: DefaultStyle.grey_100
|
|
MediumButton {
|
|
id: expandButton
|
|
anchors.top: parent.top
|
|
anchors.topMargin: Math.round(4 * DefaultStyle.dp)
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
style: ButtonStyle.noBackgroundOrange
|
|
icon.source: checked ? AppIcons.downArrow : AppIcons.upArrow
|
|
checkable: true
|
|
}
|
|
}
|
|
contentItem: RowLayout {
|
|
spacing: Math.round(20 * DefaultStyle.dp)
|
|
RowLayout {
|
|
spacing: Math.round(16 * DefaultStyle.dp)
|
|
BigButton {
|
|
id: emojiPickerButton
|
|
style: ButtonStyle.noBackground
|
|
checkable: true
|
|
icon.source: checked ? AppIcons.closeX : AppIcons.smiley
|
|
}
|
|
BigButton {
|
|
style: ButtonStyle.noBackground
|
|
icon.source: AppIcons.paperclip
|
|
onClicked: {
|
|
fileDialog.open()
|
|
}
|
|
}
|
|
Control.Control {
|
|
Layout.fillWidth: true
|
|
leftPadding: Math.round(15 * DefaultStyle.dp)
|
|
rightPadding: Math.round(15 * DefaultStyle.dp)
|
|
topPadding: Math.round(15 * DefaultStyle.dp)
|
|
bottomPadding: Math.round(15 * 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.fillWidth: true
|
|
Layout.preferredHeight: Math.min(Math.round(60 * DefaultStyle.dp), contentHeight)
|
|
Binding {
|
|
target: sendingAreaFlickable
|
|
when: expandButton.checked
|
|
property: "Layout.preferredHeight"
|
|
value: Math.round(250 * DefaultStyle.dp)
|
|
restoreMode: Binding.RestoreBindingOrValue
|
|
}
|
|
Layout.fillHeight: true
|
|
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
|
|
width: sendingAreaFlickable.width
|
|
height: sendingAreaFlickable.height
|
|
textFormat: TextEdit.AutoText
|
|
//: 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
|
|
Keys.onPressed: (event) => {
|
|
if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return))
|
|
if(!(event.modifiers & Qt.ShiftModifier)) {
|
|
mainItem.sendText()
|
|
event.accepted = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
RowLayout {
|
|
id: stackButton
|
|
spacing: 0
|
|
BigButton {
|
|
visible: sendingTextArea.text.length === 0
|
|
style: ButtonStyle.noBackground
|
|
icon.source: AppIcons.microphone
|
|
onClicked: {
|
|
console.log("TODO : go to record message")
|
|
}
|
|
}
|
|
BigButton {
|
|
visible: sendingTextArea.text.length !== 0
|
|
style: ButtonStyle.noBackgroundOrange
|
|
icon.source: AppIcons.paperPlaneRight
|
|
onClicked: {
|
|
mainItem.sendText()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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_500main
|
|
}
|
|
|
|
DashRectangle {
|
|
x: parent.x
|
|
y: parent.y
|
|
radius: hoverContent.radius
|
|
color: DefaultStyle.main2_500main
|
|
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 }
|
|
}
|
|
}
|
|
} |