mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-04-19 16:38:28 +00:00
Better chat images : view final image when hovering mouse, keep filename only for non-images, fix some clipping issues.
This commit is contained in:
parent
2d7d007b21
commit
cbe91db68d
9 changed files with 56 additions and 28 deletions
|
|
@ -7,7 +7,7 @@ import Common.Styles 1.0
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: mainItem
|
||||||
property alias text: textArea.text
|
property alias text: textArea.text
|
||||||
property alias placeholderText: textArea.placeholderText
|
property alias placeholderText: textArea.placeholderText
|
||||||
readonly property alias length: textArea.length
|
readonly property alias length: textArea.length
|
||||||
|
|
@ -15,6 +15,7 @@ Rectangle {
|
||||||
property alias font: textArea.font
|
property alias font: textArea.font
|
||||||
property alias textColor: textArea.color
|
property alias textColor: textArea.color
|
||||||
property alias readOnly: textArea.readOnly
|
property alias readOnly: textArea.readOnly
|
||||||
|
property int padding: TextAreaFieldStyle.text.padding
|
||||||
|
|
||||||
height: TextAreaFieldStyle.background.height
|
height: TextAreaFieldStyle.background.height
|
||||||
width: TextAreaFieldStyle.background.width
|
width: TextAreaFieldStyle.background.width
|
||||||
|
|
@ -50,10 +51,10 @@ Rectangle {
|
||||||
wrapMode: TextArea.Wrap
|
wrapMode: TextArea.Wrap
|
||||||
height: flickable.height
|
height: flickable.height
|
||||||
|
|
||||||
bottomPadding: TextAreaFieldStyle.text.padding
|
bottomPadding: mainItem.padding
|
||||||
leftPadding: TextAreaFieldStyle.text.padding
|
leftPadding: mainItem.padding
|
||||||
rightPadding: TextAreaFieldStyle.text.padding + Number(scrollBar.visible) * scrollBar.width
|
rightPadding: mainItem.padding + Number(scrollBar.visible) * scrollBar.width
|
||||||
topPadding: TextAreaFieldStyle.text.padding
|
topPadding: mainItem.padding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ Rectangle {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
color: ChatStyle.color
|
color: ChatStyle.color
|
||||||
|
clip: true
|
||||||
|
|
||||||
function positionViewAtIndex(index){
|
function positionViewAtIndex(index){
|
||||||
chat.bindToEnd = false
|
chat.bindToEnd = false
|
||||||
|
|
@ -76,7 +77,7 @@ Rectangle {
|
||||||
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
clip: false
|
||||||
highlightFollowsCurrentItem: false
|
highlightFollowsCurrentItem: false
|
||||||
// Use moving event => this is a user action.
|
// Use moving event => this is a user action.
|
||||||
onIsMovingChanged:{
|
onIsMovingChanged:{
|
||||||
|
|
@ -122,7 +123,7 @@ Rectangle {
|
||||||
Item {
|
Item {
|
||||||
implicitHeight: container.height + ChatStyle.sectionHeading.bottomMargin
|
implicitHeight: container.height + ChatStyle.sectionHeading.bottomMargin
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
clip: false
|
||||||
Borders {
|
Borders {
|
||||||
id: container
|
id: container
|
||||||
|
|
||||||
|
|
@ -188,6 +189,7 @@ Rectangle {
|
||||||
|
|
||||||
color: ChatStyle.color
|
color: ChatStyle.color
|
||||||
implicitHeight: layout.height + ChatStyle.entry.bottomMargin
|
implicitHeight: layout.height + ChatStyle.entry.bottomMargin
|
||||||
|
clip: false
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -198,6 +200,7 @@ Rectangle {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
implicitHeight: layout.height
|
implicitHeight: layout.height
|
||||||
width: parent.width + parent.anchors.rightMargin
|
width: parent.width + parent.anchors.rightMargin
|
||||||
|
clip: false
|
||||||
acceptedButtons: Qt.NoButton
|
acceptedButtons: Qt.NoButton
|
||||||
ColumnLayout{
|
ColumnLayout{
|
||||||
id: layout
|
id: layout
|
||||||
|
|
@ -264,6 +267,7 @@ Rectangle {
|
||||||
property int remainingIndex : loaderIndex % ((chat.remainingLoadersCount) / chat.syncLoaderBatch) != 0 // Check loader index to remaining loader.
|
property int remainingIndex : loaderIndex % ((chat.remainingLoadersCount) / chat.syncLoaderBatch) != 0 // Check loader index to remaining loader.
|
||||||
onRemainingIndexChanged: if( remainingIndex == 0 && asynchronous) asynchronous = false
|
onRemainingIndexChanged: if( remainingIndex == 0 && asynchronous) asynchronous = false
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
z:1
|
||||||
|
|
||||||
onStatusChanged: if( status == Loader.Ready) {
|
onStatusChanged: if( status == Loader.Ready) {
|
||||||
remainingIndex = -1 // overwrite to remove signal changed. That way, there is no more binding loops.
|
remainingIndex = -1 // overwrite to remove signal changed. That way, there is no more binding loops.
|
||||||
|
|
@ -315,6 +319,7 @@ Rectangle {
|
||||||
footer: Item{
|
footer: Item{
|
||||||
implicitHeight: composersItem.implicitHeight
|
implicitHeight: composersItem.implicitHeight
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
clip: false
|
||||||
Text {
|
Text {
|
||||||
id: composersItem
|
id: composersItem
|
||||||
property var composers : container.proxyModel.chatRoomModel ? container.proxyModel.chatRoomModel.composers : undefined
|
property var composers : container.proxyModel.chatRoomModel ? container.proxyModel.chatRoomModel.composers : undefined
|
||||||
|
|
@ -376,7 +381,6 @@ Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: textAreaBorders.height + chatMessagePreview.height+messageBlock.height
|
Layout.preferredHeight: textAreaBorders.height + chatMessagePreview.height+messageBlock.height
|
||||||
color: ChatStyle.sendArea.backgroundBorder.color
|
color: ChatStyle.sendArea.backgroundBorder.color
|
||||||
clip: true
|
|
||||||
ColumnLayout{
|
ColumnLayout{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ Column{
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
property bool isOutgoing : contentModel && contentModel.chatMessageModel && (contentModel.chatMessageModel.isOutgoing || contentModel.chatMessageModel.state == LinphoneEnums.ChatMessageStateIdle);
|
property bool isOutgoing : contentModel && contentModel.chatMessageModel && (contentModel.chatMessageModel.isOutgoing || contentModel.chatMessageModel.state == LinphoneEnums.ChatMessageStateIdle);
|
||||||
|
z: message.visible ? 0 : 1
|
||||||
ChatCalendarMessage{
|
ChatCalendarMessage{
|
||||||
id: calendarMessage
|
id: calendarMessage
|
||||||
contentModel: mainItem.contentModel
|
contentModel: mainItem.contentModel
|
||||||
|
|
@ -46,16 +46,19 @@ Column{
|
||||||
gotoButtonMode: 1
|
gotoButtonMode: 1
|
||||||
onExpandToggle: isExpanded=!isExpanded
|
onExpandToggle: isExpanded=!isExpanded
|
||||||
height: fitHeight
|
height: fitHeight
|
||||||
|
z: 1
|
||||||
}
|
}
|
||||||
ChatAudioMessage{
|
ChatAudioMessage{
|
||||||
id: audioMessage
|
id: audioMessage
|
||||||
contentModel: mainItem.contentModel
|
contentModel: mainItem.contentModel
|
||||||
visible: contentModel
|
visible: contentModel
|
||||||
|
z: 1
|
||||||
}
|
}
|
||||||
ChatFileMessage{
|
ChatFileMessage{
|
||||||
id: fileMessage
|
id: fileMessage
|
||||||
contentModel: mainItem.contentModel
|
contentModel: mainItem.contentModel
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
z: 2
|
||||||
}
|
}
|
||||||
ChatTextMessage {
|
ChatTextMessage {
|
||||||
id: message
|
id: message
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,14 @@ Row {
|
||||||
property ChatMessageModel chatMessageModel: contentModel && contentModel.chatMessageModel
|
property ChatMessageModel chatMessageModel: contentModel && contentModel.chatMessageModel
|
||||||
property ContentModel contentModel
|
property ContentModel contentModel
|
||||||
property bool isOutgoing : chatMessageModel && ( chatMessageModel.isOutgoing || chatMessageModel.state == LinphoneEnums.ChatMessageStateIdle);
|
property bool isOutgoing : chatMessageModel && ( chatMessageModel.isOutgoing || chatMessageModel.state == LinphoneEnums.ChatMessageStateIdle);
|
||||||
property int fitWidth: visible ? Math.max(fileName.implicitWidth + 5 + thumbnailProvider.width + 3*ChatStyle.entry.message.file.margins
|
property int fitWidth: visible ? Math.max( (fileName.visible ? fileName.implicitWidth : 0)
|
||||||
|
+ thumbnailProvider.width + 3*ChatStyle.entry.message.file.margins
|
||||||
, Math.max(ChatStyle.entry.message.file.width, ChatStyle.entry.message.outgoing.areaSize)) : 0
|
, Math.max(ChatStyle.entry.message.file.width, ChatStyle.entry.message.outgoing.areaSize)) : 0
|
||||||
property int fitHeight: visible ? rectangle.height : 0
|
property int fitHeight: visible ? rectangle.height : 0
|
||||||
|
|
||||||
|
property bool isAnimatedImage : mainRow.contentModel && mainRow.contentModel.wasDownloaded && UtilsCpp.isAnimatedImage(mainRow.contentModel.filePath)
|
||||||
|
property bool haveThumbnail: mainRow.contentModel && mainRow.contentModel.thumbnail
|
||||||
|
|
||||||
signal copyAllDone()
|
signal copyAllDone()
|
||||||
signal copySelectionDone()
|
signal copySelectionDone()
|
||||||
signal forwardClicked()
|
signal forwardClicked()
|
||||||
|
|
@ -52,7 +56,7 @@ Row {
|
||||||
property string thumbnail : mainRow.contentModel ? mainRow.contentModel.thumbnail : ''
|
property string thumbnail : mainRow.contentModel ? mainRow.contentModel.thumbnail : ''
|
||||||
color: 'transparent'
|
color: 'transparent'
|
||||||
|
|
||||||
height: thumbnail ? ChatStyle.entry.message.file.heightWithThumbnail : ChatStyle.entry.message.file.height
|
height: mainRow.isAnimatedImage ? ChatStyle.entry.message.file.heightbetter : ChatStyle.entry.message.file.height
|
||||||
width: mainRow.width
|
width: mainRow.width
|
||||||
|
|
||||||
radius: ChatStyle.entry.message.radius
|
radius: ChatStyle.entry.message.radius
|
||||||
|
|
@ -75,11 +79,21 @@ Row {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: thumbnailImageSource
|
id: thumbnailImageSource
|
||||||
|
property real scaleAnimatorTo : ChatStyle.entry.message.file.animation.thumbnailTo
|
||||||
mipmap: SettingsModel.mipmapEnabled
|
mipmap: SettingsModel.mipmapEnabled
|
||||||
source: mainRow.contentModel.thumbnail
|
source: mainRow.contentModel.thumbnail
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
//sourceSize.width: 200
|
Loader{
|
||||||
//sourceSize.height: 100
|
anchors.fill: parent
|
||||||
|
sourceComponent: Image{// Better quality on zoom
|
||||||
|
mipmap: SettingsModel.mipmapEnabled
|
||||||
|
source:'file:/'+mainRow.contentModel.filePath
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
visible: status == Image.Ready
|
||||||
|
}
|
||||||
|
asynchronous: true
|
||||||
|
active: thumbnailProvider.state == 'hovered'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
|
|
@ -87,6 +101,7 @@ Row {
|
||||||
|
|
||||||
AnimatedImage {
|
AnimatedImage {
|
||||||
id: animatedImageSource
|
id: animatedImageSource
|
||||||
|
property real scaleAnimatorTo : ChatStyle.entry.message.file.animation.to
|
||||||
mipmap: SettingsModel.mipmapEnabled
|
mipmap: SettingsModel.mipmapEnabled
|
||||||
source: 'file:/'+mainRow.contentModel.filePath
|
source: 'file:/'+mainRow.contentModel.filePath
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
|
|
@ -99,6 +114,7 @@ Row {
|
||||||
id: extension
|
id: extension
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
property real scaleAnimatorTo : ChatStyle.entry.message.file.animation.to
|
||||||
color: ChatStyle.entry.message.file.extension.background.color
|
color: ChatStyle.entry.message.file.extension.background.color
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
|
@ -120,10 +136,11 @@ Row {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.preferredWidth: parent.height*4/3
|
Layout.preferredWidth: parent.height*4/3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sourceComponent: (mainRow.contentModel ?
|
sourceComponent: (mainRow.contentModel ?
|
||||||
(mainRow.contentModel.wasDownloaded && UtilsCpp.isAnimatedImage(mainRow.contentModel.filePath)
|
(mainRow.isAnimatedImage ? animatedImage
|
||||||
? animatedImage
|
: (mainRow.haveThumbnail ? thumbnailImage : extension )
|
||||||
: (mainRow.contentModel.thumbnail ? thumbnailImage : extension )
|
|
||||||
) : undefined)
|
) : undefined)
|
||||||
|
|
||||||
ScaleAnimator {
|
ScaleAnimator {
|
||||||
|
|
@ -152,7 +169,7 @@ Row {
|
||||||
}
|
}
|
||||||
|
|
||||||
thumbnailProvider.z = Constants.zPopup
|
thumbnailProvider.z = Constants.zPopup
|
||||||
thumbnailProviderAnimator.to = ChatStyle.entry.message.file.animation.to
|
thumbnailProviderAnimator.to = thumbnailProvider.item.scaleAnimatorTo
|
||||||
thumbnailProviderAnimator.running = true
|
thumbnailProviderAnimator.running = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -203,14 +220,15 @@ Row {
|
||||||
}
|
}
|
||||||
|
|
||||||
text: (mainRow.contentModel ? mainRow.contentModel.name : '')
|
text: (mainRow.contentModel ? mainRow.contentModel.name : '')
|
||||||
width: parent.width
|
width: visible ? parent.width : 0
|
||||||
|
visible: mainRow.contentModel && !mainRow.isAnimatedImage && !mainRow.haveThumbnail
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgressBar {
|
ProgressBar {
|
||||||
id: progressBar
|
id: progressBar
|
||||||
|
|
||||||
height: ChatStyle.entry.message.file.status.bar.height
|
height: ChatStyle.entry.message.file.status.bar.height
|
||||||
width: parent.width
|
width: visible ? parent.width : 0
|
||||||
|
|
||||||
to: (mainRow.contentModel ? mainRow.contentModel.fileSize : 0)
|
to: (mainRow.contentModel ? mainRow.contentModel.fileSize : 0)
|
||||||
value: mainRow.contentModel ? mainRow.contentModel.fileOffset || to : to
|
value: mainRow.contentModel ? mainRow.contentModel.fileOffset || to : to
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,7 @@ Item {
|
||||||
anchors.topMargin: 3
|
anchors.topMargin: 3
|
||||||
anchors.leftMargin: 5
|
anchors.leftMargin: 5
|
||||||
interactive: false
|
interactive: false
|
||||||
|
clip: false
|
||||||
|
|
||||||
function updateWidth(){
|
function updateWidth(){
|
||||||
var maxWidth = 0
|
var maxWidth = 0
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ Rectangle{
|
||||||
radius: 10
|
radius: 10
|
||||||
state: chatRoomModel && chatRoomModel.reply ? 'showed' : 'hidden'
|
state: chatRoomModel && chatRoomModel.reply ? 'showed' : 'hidden'
|
||||||
// Remove bottom corners
|
// Remove bottom corners
|
||||||
clip: false
|
|
||||||
function hide(){
|
function hide(){
|
||||||
state = 'hidden'
|
state = 'hidden'
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +73,6 @@ Rectangle{
|
||||||
id: replyPreviewTextArea
|
id: replyPreviewTextArea
|
||||||
ScrollBar.vertical: ForceScrollBar {visible: replyPreviewTextArea.height < messageContentsList.height}
|
ScrollBar.vertical: ForceScrollBar {visible: replyPreviewTextArea.height < messageContentsList.height}
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
clip: true
|
|
||||||
contentHeight: messageContentsList.height
|
contentHeight: messageContentsList.height
|
||||||
contentWidth: width - ScrollBar.vertical.width
|
contentWidth: width - ScrollBar.vertical.width
|
||||||
flickableDirection: Flickable.VerticalFlick
|
flickableDirection: Flickable.VerticalFlick
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ TextEdit {
|
||||||
height: fitHeight
|
height: fitHeight
|
||||||
width: parent.width
|
width: parent.width
|
||||||
visible: contentModel && contentModel.isText()
|
visible: contentModel && contentModel.isText()
|
||||||
clip: true
|
clip: false
|
||||||
padding: ChatStyle.entry.message.padding
|
padding: ChatStyle.entry.message.padding
|
||||||
textMargin: 0
|
textMargin: 0
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ Item {
|
||||||
}
|
}
|
||||||
height: parent.height - (deliveryLayout.visible? deliveryLayout.height : 0)
|
height: parent.height - (deliveryLayout.visible? deliveryLayout.height : 0)
|
||||||
radius: ChatStyle.entry.message.radius
|
radius: ChatStyle.entry.message.radius
|
||||||
|
clip: false
|
||||||
width: (
|
width: (
|
||||||
ephemeralTimerRow.visible && dataWidth < ephemeralTimerRow.width + 2*ChatStyle.entry.message.padding
|
ephemeralTimerRow.visible && dataWidth < ephemeralTimerRow.width + 2*ChatStyle.entry.message.padding
|
||||||
? ephemeralTimerRow.width + 2*ChatStyle.entry.message.padding
|
? ephemeralTimerRow.width + 2*ChatStyle.entry.message.padding
|
||||||
|
|
@ -82,6 +82,7 @@ Item {
|
||||||
}
|
}
|
||||||
ChatReplyMessage{
|
ChatReplyMessage{
|
||||||
id: replyMessage
|
id: replyMessage
|
||||||
|
z: 1
|
||||||
mainChatMessageModel: $chatEntry
|
mainChatMessageModel: $chatEntry
|
||||||
visible: $chatEntry.isReply
|
visible: $chatEntry.isReply
|
||||||
maxWidth: container.width
|
maxWidth: container.width
|
||||||
|
|
@ -96,6 +97,7 @@ Item {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
visible: count > 0
|
visible: count > 0
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
clip: false
|
||||||
model: ContentProxyModel{
|
model: ContentProxyModel{
|
||||||
chatMessageModel: $chatEntry
|
chatMessageModel: $chatEntry
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,12 +182,12 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
property QtObject file: QtObject {
|
property QtObject file: QtObject {
|
||||||
property int height: 64
|
property int height: 80
|
||||||
property int heightWithThumbnail: 200
|
property int heightbetter: 200
|
||||||
property int iconSize: 18
|
property int iconSize: 18
|
||||||
property int margins: 8
|
property int margins: 8
|
||||||
property int spacing: 8
|
property int spacing: 8
|
||||||
property int width: 250
|
property int width: 100
|
||||||
property QtObject download: QtObject{
|
property QtObject download: QtObject{
|
||||||
property string icon: 'download_custom'
|
property string icon: 'download_custom'
|
||||||
property int iconSize: 30
|
property int iconSize: 30
|
||||||
|
|
@ -196,8 +196,9 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
property QtObject animation: QtObject {
|
property QtObject animation: QtObject {
|
||||||
property int duration: 200
|
property int duration: 300
|
||||||
property real to: 1.5
|
property real to: 1.7
|
||||||
|
property real thumbnailTo: 2
|
||||||
}
|
}
|
||||||
|
|
||||||
property QtObject extension: QtObject {
|
property QtObject extension: QtObject {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue