diff --git a/qml.qrc b/qml.qrc
index db29de3b..99bff5e8 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -203,5 +203,6 @@
src/app/mainview/components/CustomizeTipBox.qml
src/app/mainview/components/BackupTipBox.qml
src/app/mainview/components/InformativeTipBox.qml
+ src/app/commoncomponents/TimestampInfo.qml
diff --git a/src/app/commoncomponents/ContactMessageDelegate.qml b/src/app/commoncomponents/ContactMessageDelegate.qml
index b79cf28e..33c82ace 100644
--- a/src/app/commoncomponents/ContactMessageDelegate.qml
+++ b/src/app/commoncomponents/ContactMessageDelegate.qml
@@ -27,74 +27,67 @@ Column {
id: root
property bool showTime: false
- property int seq: MsgSeq.single
- property alias font: textLabel.font
-
+ property bool showDay: false
+ property int timestamp: Timestamp
+ property string formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
+ property string formattedDay: MessagesAdapter.getFormattedDay(Timestamp)
+ property int seq: MsgSeq.single//a changer par textlabel
width: ListView.view ? ListView.view.width : 0
-
spacing: 2
topPadding: 12
bottomPadding: 12
- Rectangle {
- id: msg
-
+ ColumnLayout {
anchors.horizontalCenter: parent.horizontalCenter
- width: childrenRect.width
- height: JamiTheme.contactMessageAvatarSize + 12
- radius: JamiTheme.contactMessageAvatarSize / 2 + 6
+ TimestampInfo {
+ id:timestampItem
- color: "transparent"
- border.width: 1
- border.color: CurrentConversation.isCoreDialog ? JamiTheme.messageInBgColor : CurrentConversation.color
+ showDay: root.showDay
+ showTime: root.showTime
+ formattedTime: root.formattedTime
+ formattedDay: root.formattedDay
+ Layout.alignment: Qt.AlignHCenter
+ }
- RowLayout {
- anchors.verticalCenter: parent.verticalCenter
+ Rectangle {
+ id: msg
- Avatar {
- Layout.leftMargin: 6
+ width: childrenRect.width
+ height: JamiTheme.contactMessageAvatarSize + 12
+ radius: JamiTheme.contactMessageAvatarSize / 2 + 6
+ Layout.alignment: Qt.AlignVCenter
+ color: "transparent"
+ border.width: 1
+ border.color: CurrentConversation.isCoreDialog ? JamiTheme.messageInBgColor : CurrentConversation.color
- width: JamiTheme.contactMessageAvatarSize
- height: JamiTheme.contactMessageAvatarSize
- visible: ActionUri !== ""
+ RowLayout {
+ anchors.verticalCenter: parent.verticalCenter
- imageId: ActionUri !== CurrentAccount.uri ? ActionUri : CurrentAccount.id
- showPresenceIndicator: false
- mode: ActionUri !== CurrentAccount.uri ? Avatar.Mode.Contact : Avatar.Mode.Account
- }
+ Avatar {
+ Layout.leftMargin: 6
+ width: JamiTheme.contactMessageAvatarSize
+ height: JamiTheme.contactMessageAvatarSize
+ visible: ActionUri !== ""
+ imageId: ActionUri !== CurrentAccount.uri ? ActionUri : CurrentAccount.id
+ showPresenceIndicator: false
+ mode: ActionUri !== CurrentAccount.uri ? Avatar.Mode.Contact : Avatar.Mode.Account
+ }
- Label {
- Layout.rightMargin: 6
+ Label {
+ id: textLabel
- id: textLabel
- width: parent.width
- text: Body
- horizontalAlignment: Qt.AlignHCenter
- font.pointSize: JamiTheme.contactEventPointSize
- font.bold: true
- color: JamiTheme.chatviewTextColor
+ Layout.rightMargin: 6
+ width: parent.width
+ text: Body
+ horizontalAlignment: Qt.AlignHCenter
+ font.pointSize: JamiTheme.contactEventPointSize
+ font.bold: true
+ color: JamiTheme.chatviewTextColor
+ }
}
}
}
-
- Item {
- id: infoCell
-
- width: parent.width
- height: childrenRect.height
-
- Label {
- text: MessagesAdapter.getFormattedTime(Timestamp)
- color: JamiTheme.timestampColor
- visible: showTime || seq === MsgSeq.last
- height: visible * implicitHeight
- font.pointSize: 9
-
- anchors.horizontalCenter: parent.horizontalCenter
- }
- }
-
opacity: 0
Behavior on opacity { NumberAnimation { duration: 100 } }
Component.onCompleted: opacity = 1
diff --git a/src/app/commoncomponents/DataTransferMessageDelegate.qml b/src/app/commoncomponents/DataTransferMessageDelegate.qml
index 6eb57207..d4dd426f 100644
--- a/src/app/commoncomponents/DataTransferMessageDelegate.qml
+++ b/src/app/commoncomponents/DataTransferMessageDelegate.qml
@@ -31,7 +31,12 @@ Loader {
id: root
property var mediaInfo
- property bool showTime: false
+ property bool showTime
+ property bool showDay
+ property int timestamp: Timestamp
+ property string formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
+ property string formattedDay: MessagesAdapter.getFormattedDay(Timestamp)
+
property int seq: MsgSeq.single
property string author: Author
@@ -70,7 +75,9 @@ Loader {
transferName: TransferName
transferId: Id
readers: Readers
- formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
+ timestamp: root.timestamp
+ formattedTime: root.formattedTime
+ formattedDay: root.formattedTime
extraHeight: progressBar.visible ? 18 : 0
innerContent.children: [
RowLayout {
@@ -247,6 +254,7 @@ Loader {
transferId: Id
readers: Readers
formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
+ formattedDay: MessagesAdapter.getFormattedDay(Timestamp)
bubble.visible: false
innerContent.children: [
Loader {
@@ -332,7 +340,7 @@ Loader {
sourceSize.width: width
sourceSize.height: height
source: "file:///" + Body
- property real aspectRatio: implicitWidth / implicitHeight
+ property real aspectRatio: width / implicitHeight
property real adjustedWidth: Math.min(maxSize,
Math.max(minSize,
innerContent.width - senderMargin))
diff --git a/src/app/commoncomponents/GeneratedMessageDelegate.qml b/src/app/commoncomponents/GeneratedMessageDelegate.qml
index fa37c319..d37fc013 100644
--- a/src/app/commoncomponents/GeneratedMessageDelegate.qml
+++ b/src/app/commoncomponents/GeneratedMessageDelegate.qml
@@ -29,38 +29,37 @@ Column {
id: root
property bool showTime: false
+ property bool showDay: false
property int seq: MsgSeq.single
property alias font: textLabel.font
-
+ property int timestamp: Timestamp
+ property string formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
+ property string formattedDay: MessagesAdapter.getFormattedDay(Timestamp)
width: ListView.view ? ListView.view.width : 0
-
spacing: 2
topPadding: 12
bottomPadding: 12
-
- Label {
- id: textLabel
- width: parent.width
- text: Body
- horizontalAlignment: Qt.AlignHCenter
- font.pointSize: 12
- color: JamiTheme.chatviewTextColor
- }
-
- Item {
- id: infoCell
+ ColumnLayout {
width: parent.width
- height: childrenRect.height
+
+ TimestampInfo {
+ id:timestampItem
+
+ showDay: root.showDay
+ showTime: root.showTime
+ formattedTime: root.formattedTime
+ formattedDay: root.formattedDay
+ Layout.alignment: Qt.AlignHCenter
+ }
Label {
- text: MessagesAdapter.getFormattedTime(Timestamp)
- color: JamiTheme.timestampColor
- visible: showTime || seq === MsgSeq.last
- height: visible * implicitHeight
- font.pointSize: 9
+ id: textLabel
- anchors.horizontalCenter: parent.horizontalCenter
+ text: Body
+ Layout.alignment: Qt.AlignHCenter
+ font.pointSize: 12
+ color: JamiTheme.chatviewTextColor
}
}
diff --git a/src/app/commoncomponents/SBSMessageBase.qml b/src/app/commoncomponents/SBSMessageBase.qml
index b4b07543..a2d1bc3e 100644
--- a/src/app/commoncomponents/SBSMessageBase.qml
+++ b/src/app/commoncomponents/SBSMessageBase.qml
@@ -37,26 +37,26 @@ Control {
// these MUST be set but we won't use the 'required' keyword yet
property bool isOutgoing
- property bool showTime
+ property bool showTime: false
+ property bool showDay: false
property int seq
property string author
property string transferId
property string registeredNameText
property string transferName
- property string formattedTime
+ property string formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
+ property string formattedDay: MessagesAdapter.getFormattedDay(Timestamp)
property string location
property string id: Id
property string hoveredLink
property var readers: []
-
+ property int timestamp: Timestamp
readonly property real senderMargin: 64
readonly property real avatarSize: 20
readonly property real msgRadius: 20
readonly property real hPadding: JamiTheme.sbsMessageBasePreferredPadding
-
width: ListView.view ? ListView.view.width : 0
height: mainColumnLayout.implicitHeight
-
rightPadding: hPadding
leftPadding: hPadding
@@ -64,11 +64,21 @@ Control {
id: mainColumnLayout
anchors.centerIn: parent
-
width: parent.width - hPadding * 2
-
spacing: 0
+ TimestampInfo {
+ id: timestampItem
+
+ showDay: root.showDay
+ showTime: root.showTime
+ formattedTime: root.formattedTime
+ formattedDay: root.formattedDay
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
Item {
id: usernameblock
@@ -78,7 +88,7 @@ Control {
id: username
text: UtilsAdapter.getBestNameForUri(CurrentAccount.id, Author)
font.bold: true
- visible: (seq === MsgSeq.first || seq === MsgSeq.single) && !isOutgoing
+ visible:(seq === MsgSeq.first || seq === MsgSeq.single) && !isOutgoing
font.pixelSize: JamiTheme.usernameBlockFontSize
color: JamiTheme.chatviewUsernameColor
lineHeight: JamiTheme.usernameBlockLineHeight
@@ -107,17 +117,15 @@ Control {
}
}
-
MouseArea {
id: itemMouseArea
-
+
Layout.fillWidth: true
Layout.fillHeight: true
-
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: function (mouse) {
if (mouse.button === Qt.RightButton
- && (transferId !== "" || Type === Interaction.Type.TEXT)) {
+ && (transferId !== "" || Type === Interaction.Type.TEXT)) {
// Context Menu for Transfers
ctxMenu.x = mouse.x
ctxMenu.y = mouse.y
@@ -142,8 +150,8 @@ Control {
type: seq
function getBaseColor() {
var baseColor = isOutgoing ? JamiTheme.messageOutBgColor
- : CurrentConversation.isCoreDialog ?
- JamiTheme.messageInBgColor : Qt.lighter(CurrentConversation.color, 1.5)
+ : CurrentConversation.isCoreDialog ?
+ JamiTheme.messageInBgColor : Qt.lighter(CurrentConversation.color, 1.5)
if (Id === MessagesAdapter.replyToId) {
// If we are replying to
return Qt.darker(baseColor, 1.5)
@@ -194,6 +202,7 @@ Control {
id: readsOne
visible: root.readers.length === 1 && CurrentAccount.sendReadReceipt
+
width: {
if (root.readers.length === 0)
return 0
@@ -216,28 +225,12 @@ Control {
orientation: ListView.Horizontal
Layout.preferredHeight: {
if (showTime || seq === MsgSeq.last)
- return contentHeight + formattedTimeLabel.contentHeight
+ return contentHeight + timestampItem.contentHeight
else if (readsMultiple.visible)
return JamiTheme.avatarReadReceiptSize
return 0
}
-
- Label {
- id: formattedTimeLabel
-
- text: formattedTime
- color: JamiTheme.timestampColor
- visible: showTime || seq === MsgSeq.last
- height: visible * implicitHeight
- font.pointSize: 9
- topPadding : 4
- anchors.rightMargin: status.width
- anchors.right: !isOutgoing ? undefined : readsMultiple.left
- anchors.left: isOutgoing ? undefined : parent.left
- anchors.leftMargin: avatarBlockWidth + 6
- }
-
ReadStatus {
id: readsMultiple
visible: root.readers.length > 1 && CurrentAccount.sendReadReceipt
@@ -254,7 +247,6 @@ Control {
anchors.topMargin: 1
readers: root.readers
}
-
}
}
diff --git a/src/app/commoncomponents/TextMessageDelegate.qml b/src/app/commoncomponents/TextMessageDelegate.qml
index 35b95d2f..01776997 100644
--- a/src/app/commoncomponents/TextMessageDelegate.qml
+++ b/src/app/commoncomponents/TextMessageDelegate.qml
@@ -21,7 +21,6 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
-
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
@@ -31,25 +30,21 @@ SBSMessageBase {
id : root
property bool isRemoteImage
-
property real maxMsgWidth: root.width - senderMargin - 2 * hPadding - avatarBlockWidth
-
isOutgoing: Author === ""
author: Author
readers: Readers
+ timestamp: Timestamp
formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
+ formattedDay: MessagesAdapter.getFormattedDay(Timestamp)
extraHeight: extraContent.active && !isRemoteImage ? msgRadius : -isRemoteImage
innerContent.children: [
TextEdit {
-
padding: JamiTheme.preferredMarginSize
anchors.right: isOutgoing ? parent.right : undefined
-
text: Body
-
horizontalAlignment: Text.AlignLeft
-
width: {
if (extraContent.active)
Math.max(extraContent.width,
@@ -62,9 +57,7 @@ SBSMessageBase {
height: implicitHeight
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
selectByMouse: true
-
font.pixelSize: JamiTheme.chatviewFontSize
-
font.hintingPreference: Font.PreferNoHinting
renderType: Text.NativeRendering
textFormat: Text.MarkdownText
diff --git a/src/app/commoncomponents/TimestampInfo.qml b/src/app/commoncomponents/TimestampInfo.qml
new file mode 100644
index 00000000..8ba9e3a5
--- /dev/null
+++ b/src/app/commoncomponents/TimestampInfo.qml
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2022 Savoir-faire Linux Inc.
+ * Author: Nicolas Vengeon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import "../mainview/components/"
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import net.jami.Models 1.1
+import net.jami.Adapters 1.1
+import net.jami.Constants 1.1
+
+ColumnLayout{
+ id: root
+
+ property bool showTime
+ property bool showDay
+ property string formattedTime
+ property string formattedDay
+ property real detailsOpacity: 0.6
+
+ Connections {
+ target: MessagesAdapter.messageListModel
+ function onTimestampUpdate() {
+ if (showTime || showDay) {
+ formattedTime = MessagesAdapter.getFormattedTime(Timestamp)
+ }
+ }
+ }
+
+ Item {
+ visible: showDay
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.topMargin: JamiTheme.dayTimestampTopMargin
+
+ Rectangle {
+ id: line
+
+ height: 1
+ opacity: detailsOpacity
+ color:JamiTheme.timestampColor
+ width: chatView.width - JamiTheme.timestampLinePadding
+ anchors.centerIn: parent
+ }
+
+ Rectangle {
+ id: dayRectangle
+
+ width: borderRectangle.width
+ height: borderRectangle.height
+ radius: 5
+ color: JamiTheme.chatviewBgColor
+ Layout.fillHeight: true
+ anchors.centerIn: parent
+
+ Rectangle {
+ id: borderRectangle
+
+ border { color: JamiTheme.timestampColor; width: 1}
+ opacity: detailsOpacity
+ width: formattedDayLabel.width + JamiTheme.dayTimestampVPadding
+ height: formattedDayLabel.height + JamiTheme.dayTimestampHPadding
+ radius: dayRectangle.radius
+ color: JamiTheme.transparentColor
+ }
+
+ Text {
+ id: formattedDayLabel
+
+ color: JamiTheme.chatviewTextColor
+ anchors { verticalCenter: parent.verticalCenter; horizontalCenter: parent.horizontalCenter}
+ text: formattedDay
+ font.pointSize: JamiTheme.timestampFont
+ }
+ }
+ }
+
+ Label {
+ id: formattedTimeLabel
+
+ text: formattedTime
+ Layout.bottomMargin: JamiTheme.timestampBottomMargin
+ Layout.topMargin: JamiTheme.timestampTopMargin
+ Layout.alignment: Qt.AlignHCenter
+ color: JamiTheme.timestampColor
+ visible: showTime
+ height: visible * implicitHeight
+ font.pointSize: JamiTheme.timestampFont
+ }
+}
diff --git a/src/app/constant/JamiTheme.qml b/src/app/constant/JamiTheme.qml
index 509e0561..0bccb0fe 100644
--- a/src/app/constant/JamiTheme.qml
+++ b/src/app/constant/JamiTheme.qml
@@ -321,6 +321,16 @@ Item {
property real lineEditContextMenuItemsWidth: 100
property real lineEditContextMenuSeparatorsHeight: 2
+ //TimestampInfo
+ property int timestampLinePadding: 40
+ property int dayTimestampTopMargin: 30
+ property int timestampBottomMargin: 42
+ property int timestampTopMargin: 20
+ property int dayTimestampHPadding: 16
+ property real dayTimestampVPadding: 32
+ property real timestampFont: calcSize(12)
+ property int timestampIntervalTime: 120
+
// Jami switch
property real switchIndicatorRadius: 30
diff --git a/src/app/mainview/components/MessageListView.qml b/src/app/mainview/components/MessageListView.qml
index 4ba0b162..0c435703 100644
--- a/src/app/mainview/components/MessageListView.qml
+++ b/src/app/mainview/components/MessageListView.qml
@@ -44,105 +44,95 @@ JamiListView {
MessagesAdapter.loadMoreMessages()
}
- // sequencing/timestamps (2-sided style)
- function computeTimestampVisibility(item, itemIndex) {
- if (root === undefined)
- return
- var nItem = root.itemAtIndex(itemIndex - 1)
- if (nItem && itemIndex !== root.count - 1) {
- item.showTime = (nItem.timestamp - item.timestamp) > 60 &&
- nItem.formattedTime !== item.formattedTime
- } else {
- item.showTime = true
- var pItem = root.itemAtIndex(itemIndex + 1)
- if (pItem) {
- pItem.showTime = (item.timestamp - pItem.timestamp) > 60 &&
- pItem.formattedTime !== item.formattedTime
+
+ function computeTimestampVisibility(item1, item1Index, item2, item2Index) {
+ if (item1 && item2) {
+ if (item1Index < item2Index) {
+ item1.showTime = item1.timestamp - item2.timestamp > JamiTheme.timestampIntervalTime
+ item1.showDay = item1.formattedDay !== item2.formattedDay
+ }else {
+ item2.showTime = item2.timestamp - item1.timestamp > JamiTheme.timestampIntervalTime
+ item2.showDay = item2.formattedDay !== item1.formattedDay
}
+ return true
+ }
+ return false
+ }
+
+ function computeChatview(item,itemIndex) {
+ if (!root ) return
+ var rootItem = root.itemAtIndex(0)
+ var pItem = root.itemAtIndex(itemIndex - 1)
+ var pItemIndex = itemIndex - 1
+ var nItem = root.itemAtIndex(itemIndex + 1)
+ var nItemIndex = itemIndex + 1
+ //Middle insertion
+ if (pItem && nItem) {
+ computeTimestampVisibility(item, itemIndex, nItem, nItemIndex)
+ computeSequencing(nItemIndex, nItem, root.itemAtIndex(itemIndex + 2), item)
+ }
+ //top buffer insertion = scroll up
+ if (pItem && !nItem) {
+ computeTimestampVisibility(item, itemIndex, pItem, pItemIndex)
+ computeSequencing(pItemIndex, pItem, item, root.itemAtIndex(itemIndex - 2))
+ }
+ //bottom buffer insertion = scroll down
+ if (!pItem && nItem) {
+ computeTimestampVisibility(item, itemIndex, nItem, nItemIndex)
+ computeSequencing(nItemIndex, nItem, root.itemAtIndex(itemIndex + 2), item)
+ }
+ //index 0 insertion = new message
+ if (itemIndex === 0) {
+ Qt.callLater(computeSequencing, itemIndex, item, root.itemAtIndex(itemIndex + 1), null)
+ if (! computeTimestampVisibility(item, itemIndex, nItem, nItemIndex)) {
+ Qt.callLater(computeChatview, item, itemIndex)
+ }
+ }
+ //top element
+ if(itemIndex === root.count - 1 && CurrentConversation.allMessagesLoaded) {
+ item.showTime = true
+ item.showDay = true
}
}
- function computeSequencing(computeItem, computeItemIndex) {
- if (root === undefined)
+ function computeSequencing(index, item, nItem, pItem) {
+ if (root === undefined || !item)
return
- var cItem = {
- 'author': computeItem.author,
- 'showTime': computeItem.showTime
- }
- var pItem = root.itemAtIndex(computeItemIndex + 1)
- var nItem = root.itemAtIndex(computeItemIndex - 1)
- let isSeq = (item0, item1) =>
- item0.author === item1.author && !item0.showTime
-
- let setSeq = function (newSeq, item) {
- if (item === undefined)
- computeItem.seq = newSeq
- else
- item.seq = newSeq
- }
-
- let rAdjustSeq = function (item) {
- if (item.seq === MsgSeq.last)
- item.seq = MsgSeq.middle
- else if (item.seq === MsgSeq.single)
- setSeq(MsgSeq.first, item)
- }
-
- let adjustSeq = function (item) {
- if (item.seq === MsgSeq.first)
- item.seq = MsgSeq.middle
- else if (item.seq === MsgSeq.single)
- setSeq(MsgSeq.last, item)
- }
-
- if (pItem && !nItem) {
- if (!isSeq(pItem, cItem)) {
- computeItem.seq = MsgSeq.single
- } else {
- computeItem.seq = MsgSeq.last
- rAdjustSeq(pItem)
- }
- } else if (nItem && !pItem) {
- if (!isSeq(cItem, nItem)) {
- computeItem.seq = MsgSeq.single
- } else {
- setSeq(MsgSeq.first)
- adjustSeq(nItem)
- }
- } else if (!nItem && !pItem) {
- computeItem.seq = MsgSeq.single
- } else {
- if (isSeq(pItem, nItem)) {
- if (isSeq(pItem, cItem)) {
- computeItem.seq = MsgSeq.middle
- } else {
- computeItem.seq = MsgSeq.single
-
- if (pItem.seq === MsgSeq.first)
- pItem.seq = MsgSeq.single
- else if (item.seq === MsgSeq.middle)
- pItem.seq = MsgSeq.last
-
- if (nItem.seq === MsgSeq.last)
- nItem.seq = MsgSeq.single
- else if (nItem.seq === MsgSeq.middle)
- nItem.seq = MsgSeq.first
+ function isFirst() {
+ if (!nItem) return true
+ else{
+ if (item.showTime) {
+ return true
}
- } else {
- if (!isSeq(pItem, cItem)) {
- computeItem.seq = MsgSeq.first
- adjustSeq(pItem)
- } else {
- computeItem.seq = MsgSeq.last
- rAdjustSeq(nItem)
+ if (nItem.author !== item.author) {
+ return true
}
}
+ return false
}
- if (computeItem.seq === MsgSeq.last) {
- computeItem.showTime = true
+ function isLast() {
+ if (!pItem) return true
+ else{
+ if (pItem.showTime) {
+ return true
+ }
+ if (pItem.author !== item.author) {
+ return true
+ }
+ }
+ return false
}
+
+ if (isLast() && isFirst())
+ item.seq = MsgSeq.single
+ if (!isLast() && isFirst())
+ item.seq = MsgSeq.first
+ if (isLast() && !isFirst())
+ item.seq = MsgSeq.last
+ if (!isLast() && !isFirst())
+ item.seq = MsgSeq.middle
}
// fade-in mechanism
@@ -189,6 +179,7 @@ JamiListView {
width: parent.width
// this offscreen caching is pretty huge
// displayMarginEnd may be removed
+
displayMarginBeginning: 2048
displayMarginEnd: 2048
maximumFlickVelocity: 2048
@@ -216,65 +207,55 @@ JamiListView {
id: delegateChooser
role: "Type"
+
DelegateChoice {
+ id: delegateChoice
+
roleValue: Interaction.Type.TEXT
+
TextMessageDelegate {
- Component.onCompleted: {
- if (index) {
- computeTimestampVisibility(this, index)
- computeSequencing(this, index)
- } else {
- Qt.callLater(computeTimestampVisibility, this, index)
- Qt.callLater(computeSequencing, this, index)
- }
+ Component.onCompleted: {
+ computeChatview(this,index)
}
}
}
+
DelegateChoice {
roleValue: Interaction.Type.CALL
+
GeneratedMessageDelegate {
- Component.onCompleted: {
- if (index)
- computeTimestampVisibility(this, index)
- else
- Qt.callLater(computeTimestampVisibility, this, index)
+ Component.onCompleted: {
+ computeChatview(this,index)
}
}
}
+
DelegateChoice {
roleValue: Interaction.Type.CONTACT
+
ContactMessageDelegate {
- Component.onCompleted: {
- if (index)
- computeTimestampVisibility(this, index)
- else
- Qt.callLater(computeTimestampVisibility, this, index)
+ Component.onCompleted: {
+ computeChatview(this,index)
}
}
}
+
DelegateChoice {
roleValue: Interaction.Type.INITIAL
+
GeneratedMessageDelegate {
font.bold: true
- Component.onCompleted: {
- if (index)
- computeTimestampVisibility(this, index)
- else
- Qt.callLater(computeTimestampVisibility, this, index)
+ Component.onCompleted: {
+ computeChatview(this,index)
}
}
}
DelegateChoice {
roleValue: Interaction.Type.DATA_TRANSFER
+
DataTransferMessageDelegate {
- Component.onCompleted: {
- if (index) {
- computeTimestampVisibility(this, index)
- computeSequencing(this, index)
- } else {
- Qt.callLater(computeTimestampVisibility, this, index)
- Qt.callLater(computeSequencing, this, index)
- }
+ Component.onCompleted: {
+ computeChatview(this,index)
}
}
}
@@ -382,8 +363,8 @@ JamiListView {
else {
var textSize = JamiQmlUtils.getTextBoundingRect(font, text).width
var typingContentWidth = typingDots.width + typingDots.anchors.leftMargin
- + typeIndicatorNameText.anchors.leftMargin
- + typeIndicatorEndingText.contentWidth
+ + typeIndicatorNameText.anchors.leftMargin
+ + typeIndicatorEndingText.contentWidth
typeIndicatorNameText.Layout.preferredWidth =
Math.min(typeIndicatorContainer.width - 5 - typingContentWidth,
textSize)
diff --git a/src/app/messagesadapter.cpp b/src/app/messagesadapter.cpp
index fd37fcc1..b3ae25b3 100644
--- a/src/app/messagesadapter.cpp
+++ b/src/app/messagesadapter.cpp
@@ -581,21 +581,41 @@ MessagesAdapter::getFormattedTime(const quint64 timestamp)
{
const auto now = QDateTime::currentDateTime();
const auto seconds = now.toSecsSinceEpoch() - timestamp;
- auto interval = qFloor(seconds / (3600 * 24));
- if (interval > 5)
- return QLocale::system().toString(QDateTime::fromSecsSinceEpoch(timestamp),
- QLocale::ShortFormat);
- if (interval > 1)
- return QObject::tr("%1 days ago").arg(interval);
- if (interval == 1)
- return QObject::tr("one day ago");
- interval = qFloor(seconds / 3600);
- if (interval > 1)
- return QObject::tr("%1 hours ago").arg(interval);
- if (interval == 1)
- return QObject::tr("one hour ago");
- interval = qFloor(seconds / 60);
- if (interval > 1)
- return QObject::tr("%1 minutes ago").arg(interval);
+ auto interval = qFloor(seconds / 60);
+
+ if (interval > 1) {
+ auto curLang = settingsManager_->getValue(Settings::Key::LANG);
+ auto curLocal(QLocale(curLang.toString()));
+ auto curTime = QDateTime::fromSecsSinceEpoch(timestamp).time();
+ QString timeLocale;
+ if (curLang == "SYSTEM")
+ timeLocale = QLocale::system().toString(curTime, QLocale::system().ShortFormat);
+ else
+ timeLocale = curLocal.toString(curTime, curLocal.ShortFormat);
+
+ return timeLocale;
+ }
return QObject::tr("just now");
}
+
+QString
+MessagesAdapter::getFormattedDay(const quint64 timestamp)
+{
+ auto now = QDate::currentDate();
+ auto before = QDateTime::fromSecsSinceEpoch(timestamp).date();
+ if (before == now)
+ return QObject::tr("Today");
+ if (before.daysTo(now) == 1)
+ return QObject::tr("Yesterday");
+
+ auto curLang = settingsManager_->getValue(Settings::Key::LANG);
+ auto curLocal(QLocale(curLang.toString()));
+ auto curDate = QDateTime::fromSecsSinceEpoch(timestamp).date();
+ QString dateLocale;
+ if (curLang == "SYSTEM")
+ dateLocale = QLocale::system().toString(curDate, QLocale::system().ShortFormat);
+ else
+ dateLocale = curLocal.toString(curDate, curLocal.ShortFormat);
+
+ return dateLocale;
+}
diff --git a/src/app/messagesadapter.h b/src/app/messagesadapter.h
index a01f1d12..21097934 100644
--- a/src/app/messagesadapter.h
+++ b/src/app/messagesadapter.h
@@ -79,6 +79,7 @@ protected:
Q_INVOKABLE QVariantMap isLocalImage(const QString& mimeName);
Q_INVOKABLE QVariantMap getMediaInfo(const QString& msg);
Q_INVOKABLE bool isRemoteImage(const QString& msg);
+ Q_INVOKABLE QString getFormattedDay(const quint64 timestamp);
Q_INVOKABLE QString getFormattedTime(const quint64 timestamp);
Q_INVOKABLE void parseMessageUrls(const QString& messageId,
const QString& msg,
diff --git a/src/app/settingsview/components/SettingSpinBox.qml b/src/app/settingsview/components/SettingSpinBox.qml
index 1685f417..0c432985 100644
--- a/src/app/settingsview/components/SettingSpinBox.qml
+++ b/src/app/settingsview/components/SettingSpinBox.qml
@@ -62,7 +62,6 @@ RowLayout {
Layout.preferredWidth: root.itemWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.alignment: Qt.AlignCenter
-
font.pointSize: JamiTheme.buttonFontSize
font.kerning: true
@@ -91,7 +90,6 @@ RowLayout {
MaterialToolTip {
id: toolTip
-
parent: textField
visible: textField.hovered && (root.tooltipText.length > 0)
delay: Qt.styleHints.mousePressAndHoldInterval
diff --git a/src/libclient/messagelistmodel.cpp b/src/libclient/messagelistmodel.cpp
index affb368a..f796f6fd 100644
--- a/src/libclient/messagelistmodel.cpp
+++ b/src/libclient/messagelistmodel.cpp
@@ -36,7 +36,11 @@ using reverseIterator = MessageListModel::reverseIterator;
MessageListModel::MessageListModel(QObject* parent)
: QAbstractListModel(parent)
-{}
+ , timestampTimer_(new QTimer(this))
+{
+ connect(timestampTimer_, &QTimer::timeout, this, &MessageListModel::timestampUpdate);
+ timestampTimer_->start(1000);
+}
QPair
MessageListModel::emplace(const QString& msgId, interaction::Info message, bool beginning)
diff --git a/src/libclient/messagelistmodel.h b/src/libclient/messagelistmodel.h
index ba7cadac..88028550 100644
--- a/src/libclient/messagelistmodel.h
+++ b/src/libclient/messagelistmodel.h
@@ -22,6 +22,7 @@
#include "api/interaction.h"
#include
+#include
namespace lrc {
namespace api {
@@ -125,6 +126,8 @@ public:
void emitDataChanged(iterator it, VectorInt roles = {});
void emitDataChanged(const QString& msgId, VectorInt roles = {});
+ Q_SIGNAL void timestampUpdate();
+
protected:
using Role = MessageList::Role;
@@ -144,6 +147,8 @@ private:
iterator insertMessage(iterator it, item_t& message);
void removeMessage(int index, iterator it);
void moveMessage(int from, int to);
+
+ QTimer* timestampTimer_ {nullptr};
};
} // namespace api
} // namespace lrc