Commit 1ea9cb67 authored by Ronan Abhamon's avatar Ronan Abhamon

fix(ui/modules/Linphone/Chat/Chat): display component correctly (not a ugly white foreground)

parent 09fa8a86
...@@ -9,7 +9,7 @@ import Utils 1.0 ...@@ -9,7 +9,7 @@ import Utils 1.0
// ============================================================================= // =============================================================================
ColumnLayout { Rectangle {
property alias proxyModel: chat.model property alias proxyModel: chat.model
// Unable to use it in style file at this moment. // Unable to use it in style file at this moment.
...@@ -27,262 +27,264 @@ ColumnLayout { ...@@ -27,262 +27,264 @@ ColumnLayout {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
spacing: 0 color: _backgroundColor
ColumnLayout {
Rectangle {
anchors.fill: parent anchors.fill: parent
color: _backgroundColor spacing: 0
}
ScrollableListView {
id: chat
// ------------------------------------------------------------------------- ScrollableListView {
id: chat
property bool _tryToLoadMoreEntries: true // -----------------------------------------------------------------------
// ------------------------------------------------------------------------- property bool _tryToLoadMoreEntries: true
function _loadMoreEntries () { // -----------------------------------------------------------------------
if (atYBeginning && !_tryToLoadMoreEntries) {
_tryToLoadMoreEntries = true
positionViewAtBeginning()
proxyModel.loadMoreEntries()
}
}
// ------------------------------------------------------------------------- function _loadMoreEntries () {
if (atYBeginning && !_tryToLoadMoreEntries) {
_tryToLoadMoreEntries = true
positionViewAtBeginning()
proxyModel.loadMoreEntries()
}
}
Layout.fillHeight: true // -----------------------------------------------------------------------
Layout.fillWidth: true
section { Layout.fillHeight: true
criteria: ViewSection.FullString Layout.fillWidth: true
delegate: sectionHeading
property: '$sectionDate'
}
// ------------------------------------------------------------------------- section {
criteria: ViewSection.FullString
delegate: sectionHeading
property: '$sectionDate'
}
Component.onCompleted: { // -----------------------------------------------------------------------
function goToEnd () {
return Utils.setTimeout(chat, 100, function () {
if (_bindToEnd) {
positionViewAtEnd()
}
return goToEnd() Component.onCompleted: {
}) function goToEnd () {
} return Utils.setTimeout(chat, 100, function () {
goToEnd() if (_bindToEnd) {
positionViewAtEnd()
}
var initView = function () { return goToEnd()
_tryToLoadMoreEntries = false })
_bindToEnd = true }
goToEnd()
positionViewAtEnd() var initView = function () {
} _tryToLoadMoreEntries = false
_bindToEnd = true
// Received only if more entries were loaded. positionViewAtEnd()
proxyModel.moreEntriesLoaded.connect(function (n) { }
positionViewAtIndex(n - 1, ListView.Beginning)
_tryToLoadMoreEntries = false
})
// When the view is changed (for example `Calls` -> `Messages`), // Received only if more entries were loaded.
// the position is set at end and it can be possible to load proxyModel.moreEntriesLoaded.connect(function (n) {
// more entries. positionViewAtIndex(n - 1, ListView.Beginning)
proxyModel.entryTypeFilterChanged.connect(initView) _tryToLoadMoreEntries = false
})
// First render. // When the view is changed (for example `Calls` -> `Messages`),
initView() // the position is set at end and it can be possible to load
} // more entries.
proxyModel.entryTypeFilterChanged.connect(initView)
onMovementStarted: _bindToEnd = false // First render.
onMovementEnded: { initView()
if (atYEnd) {
_bindToEnd = true
} }
}
onContentYChanged: _loadMoreEntries() onMovementStarted: _bindToEnd = false
onMovementEnded: {
// ------------------------------------------------------------------------- if (atYEnd) {
// Heading. _bindToEnd = true
// ------------------------------------------------------------------------- }
}
Component { onContentYChanged: _loadMoreEntries()
id: sectionHeading
Item { // -----------------------------------------------------------------------
implicitHeight: container.height + ChatStyle.sectionHeading.bottomMargin // Heading.
width: parent.width // -----------------------------------------------------------------------
Borders { Component {
id: container id: sectionHeading
borderColor: ChatStyle.sectionHeading.border.color Item {
bottomWidth: ChatStyle.sectionHeading.border.width implicitHeight: container.height + ChatStyle.sectionHeading.bottomMargin
implicitHeight: text.contentHeight +
ChatStyle.sectionHeading.padding * 2 +
ChatStyle.sectionHeading.border.width * 2
topWidth: ChatStyle.sectionHeading.border.width
width: parent.width width: parent.width
Text { Borders {
id: text id: container
anchors.fill: parent borderColor: ChatStyle.sectionHeading.border.color
color: ChatStyle.sectionHeading.text.color bottomWidth: ChatStyle.sectionHeading.border.width
font { implicitHeight: text.contentHeight +
bold: true ChatStyle.sectionHeading.padding * 2 +
pointSize: ChatStyle.sectionHeading.text.fontSize ChatStyle.sectionHeading.border.width * 2
topWidth: ChatStyle.sectionHeading.border.width
width: parent.width
Text {
id: text
anchors.fill: parent
color: ChatStyle.sectionHeading.text.color
font {
bold: true
pointSize: ChatStyle.sectionHeading.text.fontSize
}
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
// Cast section to integer because Qt converts the
// sectionDate in string!!!
text: new Date(section).toLocaleDateString(
Qt.locale(App.locale())
)
} }
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
// Cast section to integer because Qt converts the
// sectionDate in string!!!
text: new Date(section).toLocaleDateString(
Qt.locale(App.locale())
)
} }
} }
} }
}
// ------------------------------------------------------------------------- // -----------------------------------------------------------------------
// Message/Event renderer. // Message/Event renderer.
// ------------------------------------------------------------------------- // -----------------------------------------------------------------------
delegate: Rectangle { delegate: Rectangle {
id: entry id: entry
function isHoverEntry () { function isHoverEntry () {
return mouseArea.containsMouse return mouseArea.containsMouse
} }
function removeEntry () { function removeEntry () {
proxyModel.removeEntry(index) proxyModel.removeEntry(index)
} }
anchors { anchors {
left: parent ? parent.left : undefined left: parent ? parent.left : undefined
leftMargin: ChatStyle.entry.leftMargin leftMargin: ChatStyle.entry.leftMargin
right: parent ? parent.right : undefined right: parent ? parent.right : undefined
// Ugly. I admit it, but it exists a problem, without these // Ugly. I admit it, but it exists a problem, without these
// lines the extra content message is truncated. // lines the extra content message is truncated.
// I have no other solution at this moment with `anchors` // I have no other solution at this moment with `anchors`
// properties... The messages use the `implicitWidth/Height` // properties... The messages use the `implicitWidth/Height`
// and `width/Height` attrs and is not easy to found a fix. // and `width/Height` attrs and is not easy to found a fix.
rightMargin: ChatStyle.entry.deleteIconSize + rightMargin: ChatStyle.entry.deleteIconSize +
ChatStyle.entry.message.extraContent.spacing + ChatStyle.entry.message.extraContent.spacing +
ChatStyle.entry.message.extraContent.rightMargin + ChatStyle.entry.message.extraContent.rightMargin +
ChatStyle.entry.message.extraContent.leftMargin + ChatStyle.entry.message.extraContent.leftMargin +
ChatStyle.entry.message.outgoing.sendIconSize ChatStyle.entry.message.outgoing.sendIconSize
} }
color: _backgroundColor color: _backgroundColor
implicitHeight: layout.height + ChatStyle.entry.bottomMargin implicitHeight: layout.height + ChatStyle.entry.bottomMargin
// ----------------------------------------------------------------------- // ---------------------------------------------------------------------
// Avoid the use of explicit qrc paths. // Avoid the use of explicit qrc paths.
Component { Component {
id: event id: event
Event {} Event {}
} }
Component { Component {
id: incomingMessage id: incomingMessage
IncomingMessage {} IncomingMessage {}
} }
Component { Component {
id: outgoingMessage id: outgoingMessage
OutgoingMessage {} OutgoingMessage {}
} }
Component { Component {
id: fileMessage id: fileMessage
FileMessage {} FileMessage {}
} }
// ----------------------------------------------------------------------- // ---------------------------------------------------------------------
MouseArea {
id: mouseArea
hoverEnabled: true
implicitHeight: layout.height
width: parent.width + parent.anchors.rightMargin
RowLayout {
id: layout
spacing: 0
width: entry.width
// Display time.
Text {
Layout.alignment: Qt.AlignTop
Layout.preferredHeight: ChatStyle.entry.lineHeight
Layout.preferredWidth: ChatStyle.entry.time.width
color: ChatStyle.entry.time.color
font.pointSize: ChatStyle.entry.time.fontSize
text: $chatEntry.timestamp.toLocaleString(
Qt.locale(App.locale()),
'hh:mm'
)
verticalAlignment: Text.AlignVCenter
}
MouseArea { // Display content.
id: mouseArea Loader {
Layout.fillWidth: true
hoverEnabled: true sourceComponent: {
implicitHeight: layout.height if ($chatEntry.fileName) {
width: parent.width + parent.anchors.rightMargin return fileMessage
}
RowLayout {
id: layout
spacing: 0
width: entry.width
// Display time.
Text {
Layout.alignment: Qt.AlignTop
Layout.preferredHeight: ChatStyle.entry.lineHeight
Layout.preferredWidth: ChatStyle.entry.time.width
color: ChatStyle.entry.time.color
font.pointSize: ChatStyle.entry.time.fontSize
text: $chatEntry.timestamp.toLocaleString(
Qt.locale(App.locale()),
'hh:mm'
)
verticalAlignment: Text.AlignVCenter
}
// Display content. if ($chatEntry.type === ChatModel.CallEntry) {
Loader { return event
Layout.fillWidth: true }
sourceComponent: {
if ($chatEntry.fileName) {
return fileMessage
}
if ($chatEntry.type === ChatModel.CallEntry) { return $chatEntry.isOutgoing ? outgoingMessage : incomingMessage
return event
} }
return $chatEntry.isOutgoing ? outgoingMessage : incomingMessage
} }
} }
} }
} }
} }
}
// --------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Send area. // Send area.
// --------------------------------------------------------------------------- // -------------------------------------------------------------------------
Borders { Borders {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: ChatStyle.sendArea.height + Layout.preferredHeight: ChatStyle.sendArea.height +
ChatStyle.sendArea.border.width ChatStyle.sendArea.border.width
borderColor: ChatStyle.sendArea.border.color borderColor: ChatStyle.sendArea.border.color
topWidth: ChatStyle.sendArea.border.width topWidth: ChatStyle.sendArea.border.width
DroppableTextArea { DroppableTextArea {
anchors.fill: parent anchors.fill: parent
dropEnabled: SettingsModel.fileTransferUrl.length > 0 dropEnabled: SettingsModel.fileTransferUrl.length > 0
dropDisabledReason: qsTr('noFileTransferUrl') dropDisabledReason: qsTr('noFileTransferUrl')
placeholderText: qsTr('newMessagePlaceholder') placeholderText: qsTr('newMessagePlaceholder')
onDropped: { onDropped: {
_bindToEnd = true _bindToEnd = true
files.forEach(proxyModel.sendFileMessage) files.forEach(proxyModel.sendFileMessage)
} }
onValidText: { onValidText: {
this.text = '' this.text = ''
_bindToEnd = true _bindToEnd = true
proxyModel.sendMessage(text) proxyModel.sendMessage(text)
}
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment