mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-02-07 15:08:24 +00:00
- Split content type to be filtered by proxy lists. - Add a message in notification when receiving a conference invitation. - Change chat bubbles colors to match mobile application. - Change date display on messages to remove sections. It allows to be more coherent when sorting messages. - Change Chat Layout : outgoing messages to right, incoming messages to left. - Change bubble design to be squared when grouped. - Group messages on 1 second away from previous (and same sender). - Add a background color with radius to files in reply messages. - Make color corners on reply. - Fix filename to 2 lines in file download icon. - Add a background color on conference invitations. - Change conference title from bold to normal on invitations. - Rework chat message content layout to be used with grids and lists : files are now displayed in grid. - Remove cyclic dependencies with reply design (which was recursivly linked with ChatContent). - Fix center layouts that were not bind to the correct one. - Align pictures to center. - Fix hidden admin usernames in participant view.
214 lines
6.5 KiB
QML
214 lines
6.5 KiB
QML
import QtQuick 2.7
|
|
import QtQuick.Layouts 1.3
|
|
|
|
import Clipboard 1.0
|
|
import Common 1.0
|
|
import Linphone 1.0
|
|
|
|
import Common.Styles 1.0
|
|
import Linphone.Styles 1.0
|
|
import TextToSpeech 1.0
|
|
import Utils 1.0
|
|
import Units 1.0
|
|
import UtilsCpp 1.0
|
|
import LinphoneEnums 1.0
|
|
|
|
import ColorsList 1.0
|
|
|
|
// =============================================================================
|
|
// Simple content display without reply and forward. These modules need to be splitted because of cyclic dependencies.
|
|
// See ChatFullContent
|
|
|
|
Loader{// Use of Loader because of Repeater (items cannot be loaded dynamically)
|
|
id: mainItem
|
|
property ChatMessageModel chatMessageModel: null
|
|
property int availableWidth //const
|
|
property int fileWidth: ChatStyle.entry.message.file.height * 4 / 3 + 2*ChatStyle.entry.message.file.margins
|
|
|
|
// Readonly
|
|
property int bestWidth: Math.min(availableWidth, Math.max(filesBestWidth, conferencesBestWidth, textsBestWidth, voicesBestWidth))
|
|
property int filesBestWidth: 0
|
|
property int filesCount: 0
|
|
property int conferencesCount: 0
|
|
property int conferencesBestWidth: 0
|
|
property int textsBestWidth: 0
|
|
property int textsCount: 0
|
|
property int voicesBestWidth: 0
|
|
property int voicesCount: 0
|
|
|
|
signal isFileHoveringChanged(bool isFileHovering)
|
|
signal lastTextSelectedChanged(string lastTextSelected)
|
|
signal rightClicked()
|
|
signal conferenceIcsCopied()
|
|
|
|
property bool useTextColor: false
|
|
property color textColor
|
|
|
|
property int fileBorderWidth : 0
|
|
property color fileBackgroundColor: ChatStyle.entry.message.file.extension.background.colorModel.color
|
|
property int fileBackgroundRadius: ChatStyle.entry.message.file.extension.radius
|
|
|
|
active: chatMessageModel
|
|
|
|
sourceComponent: Component{
|
|
Column{
|
|
id: mainComponent
|
|
spacing: 0
|
|
function updateFilesBestWidth(){
|
|
var newBestWidth = 0
|
|
var count = 0
|
|
for(var child in messageFilesList.children) {
|
|
var item = messageFilesList.children[child]
|
|
if(item){
|
|
var a = item.fitWidth
|
|
if(a) {
|
|
++count
|
|
newBestWidth = Math.max(newBestWidth,a)
|
|
}
|
|
}
|
|
}
|
|
if(count > 1){
|
|
newBestWidth = Math.max(newBestWidth, mainItem.fileWidth*count)
|
|
}
|
|
mainItem.filesCount = count
|
|
mainItem.filesBestWidth = newBestWidth
|
|
}
|
|
function updateListBestWidth(listView){
|
|
var newBestWidth = 0
|
|
var count = 0
|
|
for(var child in listView.contentItem.children) {
|
|
var a = listView.contentItem.children[child].fitWidth
|
|
if(a) {
|
|
++count
|
|
newBestWidth = Math.max(newBestWidth,a)
|
|
}
|
|
}
|
|
return [count, newBestWidth];
|
|
}
|
|
ListView {
|
|
id: messagesVoicesList
|
|
width: parent.width
|
|
visible: count > 0
|
|
spacing: 0
|
|
clip: false
|
|
model: ContentProxyModel{
|
|
filter: ContentProxyModel.ContentType.Voice
|
|
chatMessageModel: mainItem.chatMessageModel
|
|
}
|
|
height: contentHeight
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
interactive: false
|
|
function updateBestWidth(){
|
|
var newWidth = mainComponent.updateListBestWidth(messagesVoicesList)
|
|
mainItem.voicesCount = newWidth[0]
|
|
mainItem.voicesBestWidth = newWidth[1]
|
|
}
|
|
delegate: ChatAudioMessage{
|
|
id: audioMessage
|
|
contentModel: $modelData
|
|
visible: contentModel
|
|
z: 1
|
|
Component.onCompleted: messagesVoicesList.updateBestWidth()
|
|
}
|
|
Component.onCompleted: messagesVoicesList.updateBestWidth
|
|
}
|
|
// CONFERENCE
|
|
ListView {
|
|
id: messagesConferencesList
|
|
width: parent.width
|
|
visible: count > 0
|
|
spacing: 0
|
|
clip: false
|
|
model: ContentProxyModel{
|
|
filter: ContentProxyModel.ContentType.Conference
|
|
chatMessageModel: mainItem.chatMessageModel
|
|
}
|
|
height: contentHeight
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
interactive: false
|
|
function updateBestWidth(){
|
|
var newWidth = mainComponent.updateListBestWidth(messagesConferencesList)
|
|
mainItem.conferencesCount = newWidth[0]
|
|
mainItem.conferencesBestWidth = newWidth[1]
|
|
}
|
|
Component.onCompleted: messagesConferencesList.updateBestWidth()
|
|
delegate: ChatConferenceInvitationMessage{
|
|
id: calendarMessage
|
|
contentModel: $modelData
|
|
width: parent.width
|
|
availableWidth: mainItem.availableWidth
|
|
gotoButtonMode: 1
|
|
onExpandToggle: isExpanded=!isExpanded
|
|
height: fitHeight
|
|
z: 1
|
|
onConferenceIcsCopied:mainItem.conferenceIcsCopied()
|
|
onFitWidthChanged: messagesConferencesList.updateBestWidth()
|
|
Component.onCompleted: messagesConferencesList.updateBestWidth()
|
|
}
|
|
}
|
|
// FILES
|
|
GridLayout {
|
|
id: messageFilesList
|
|
property alias count: repeater.count
|
|
visible: count > 0
|
|
clip: false
|
|
|
|
property int availableSection: mainItem.availableWidth / mainItem.fileWidth
|
|
property int bestFitSection: mainItem.bestWidth / mainItem.fileWidth
|
|
columns: Math.max(1, Math.min(availableSection , bestFitSection))
|
|
columnSpacing: 0
|
|
rowSpacing: 0
|
|
width: parent.width
|
|
Repeater{
|
|
id: repeater
|
|
model: ContentProxyModel{
|
|
filter: ContentProxyModel.ContentType.File
|
|
chatMessageModel: mainItem.chatMessageModel
|
|
}
|
|
ChatFileMessage{
|
|
contentModel: $modelData
|
|
onIsHoveringChanged: mainItem.isFileHoveringChanged(isHovering)
|
|
borderWidth: mainItem.fileBorderWidth
|
|
backgroundColor: mainItem.fileBackgroundColor
|
|
backgroundRadius: mainItem.fileBackgroundRadius
|
|
Component.onCompleted: mainComponent.updateFilesBestWidth()
|
|
}
|
|
}
|
|
}
|
|
// TEXTS
|
|
ListView {
|
|
id: messagesTextsList
|
|
width: parent.width
|
|
visible: count > 0
|
|
spacing: 0
|
|
clip: false
|
|
model: ContentProxyModel{
|
|
filter: ContentProxyModel.ContentType.Text
|
|
chatMessageModel: mainItem.chatMessageModel
|
|
}
|
|
height: contentHeight
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
interactive: false
|
|
function updateBestWidth(){
|
|
var newWidth = mainComponent.updateListBestWidth(messagesTextsList)
|
|
mainItem.textsCount = newWidth[0]
|
|
mainItem.textsBestWidth = newWidth[1]
|
|
}
|
|
Component.onCompleted: messagesTextsList.updateBestWidth()
|
|
delegate:
|
|
ChatTextMessage {
|
|
contentModel: $modelData
|
|
onLastTextSelectedChanged: mainItem.lastTextSelectedChanged(lastTextSelected)
|
|
color: mainItem.useTextColor
|
|
? mainItem.textColor
|
|
: $modelData.isOutgoing
|
|
? ChatStyle.entry.message.outgoing.text.colorModel.color
|
|
: ChatStyle.entry.message.incoming.text.colorModel.color
|
|
onRightClicked: mainItem.rightClicked()
|
|
onFitWidthChanged: messagesTextsList.updateBestWidth()
|
|
Component.onCompleted: messagesTextsList.updateBestWidth()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|