mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-07-19 06:55:24 +02:00
ConversationBubble: add time inside bubble
GitLab: #1325 Change-Id: Ib52222f4adae911e0975f4d7e8bc60739fb63cfb
This commit is contained in:
parent
4a3a49b0ec
commit
04a57dfdbb
8 changed files with 156 additions and 85 deletions
|
@ -56,13 +56,6 @@ SBSMessageBase {
|
|||
visible: isActive || ConfId === "" || Duration > 0
|
||||
|
||||
property var baseColor: isOutgoing? CurrentConversation.color : JamiTheme.messageInBgColor
|
||||
bubble.color: {
|
||||
if (ConfId === "" && Duration === 0) {
|
||||
// If missed, we can add a darker pattern
|
||||
return Qt.lighter(root.baseColor, 1.15)
|
||||
}
|
||||
return root.baseColor
|
||||
}
|
||||
|
||||
innerContent.children: [
|
||||
RowLayout {
|
||||
|
@ -73,9 +66,10 @@ SBSMessageBase {
|
|||
|
||||
Label {
|
||||
id: callLabel
|
||||
padding: 10
|
||||
|
||||
Layout.margins: 8
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: root.timeWidth + 16
|
||||
|
||||
text: {
|
||||
if (root.isActive)
|
||||
|
|
|
@ -79,6 +79,9 @@ Loader {
|
|||
formattedTime: root.formattedTime
|
||||
formattedDay: root.formattedTime
|
||||
extraHeight: progressBar.visible ? 18 : 0
|
||||
Component.onCompleted: bubble.timestampItem.visible = false
|
||||
|
||||
|
||||
innerContent.children: [
|
||||
RowLayout {
|
||||
id: transferItem
|
||||
|
@ -257,6 +260,7 @@ Loader {
|
|||
id: localMediaMsgItem
|
||||
|
||||
isOutgoing: Author === CurrentAccount.uri
|
||||
property var transferStats: MessagesAdapter.getTransferStats(Id, Status)
|
||||
showTime: root.showTime
|
||||
seq: root.seq
|
||||
author: Author
|
||||
|
@ -266,7 +270,21 @@ Loader {
|
|||
readers: Readers
|
||||
formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
|
||||
formattedDay: MessagesAdapter.getFormattedDay(Timestamp)
|
||||
bubble.visible: false
|
||||
|
||||
Component.onCompleted: {
|
||||
if (transferStats.totalSize !== undefined) {
|
||||
var totalSize = transferStats.totalSize !== 0 ? transferStats.totalSize : TotalSize
|
||||
var txt = UtilsAdapter.humanFileSize(totalSize)
|
||||
}
|
||||
bubble.timestampItem.timeLabel.text += " - " + txt
|
||||
|
||||
bubble.color = "transparent"
|
||||
bubble.timestampItem.timeColor = JamiTheme.whiteColor
|
||||
bubble.timestampItem.timeLabel.opacity = 1
|
||||
bubble.z = 1
|
||||
|
||||
}
|
||||
|
||||
innerContent.children: [
|
||||
Loader {
|
||||
id: localMediaCompLoader
|
||||
|
@ -296,6 +314,7 @@ Loader {
|
|||
}
|
||||
Component {
|
||||
id: animatedImageComp
|
||||
|
||||
AnimatedImage {
|
||||
id: animatedImg
|
||||
|
||||
|
@ -337,6 +356,22 @@ Loader {
|
|||
}
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
LinearGradient {
|
||||
id: gradient
|
||||
anchors.fill: parent
|
||||
start: Qt.point(0, height / 3)
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: JamiTheme.transparentColor
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: JamiTheme.darkGreyColorOpacityFade
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,6 +429,22 @@ Loader {
|
|||
}
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
|
||||
LinearGradient {
|
||||
id: gradient
|
||||
anchors.fill: parent
|
||||
start: Qt.point(0, height / 3)
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: JamiTheme.transparentColor
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: JamiTheme.darkGreyColorOpacityFade
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ Rectangle {
|
|||
|
||||
Rectangle {
|
||||
id: mask
|
||||
|
||||
visible: type !== MsgSeq.single && !isReply
|
||||
z: -1
|
||||
radius: 5
|
||||
|
|
|
@ -49,7 +49,7 @@ Control {
|
|||
property int timestamp: Timestamp
|
||||
readonly property real senderMargin: 64
|
||||
readonly property real avatarSize: 20
|
||||
readonly property real msgRadius: 20
|
||||
readonly property real msgRadius: 10
|
||||
readonly property real hPadding: JamiTheme.sbsMessageBasePreferredPadding
|
||||
property bool textHovered: false
|
||||
property alias replyAnimation: selectAnimation
|
||||
|
@ -59,8 +59,11 @@ Control {
|
|||
property real textContentWidth
|
||||
property real textContentHeight
|
||||
property bool isReply: ReplyTo !== ""
|
||||
property real timeWidth: timestampItem.width
|
||||
property real editedWidth: editedRow.visible ? editedRow.width + 10 : 0
|
||||
|
||||
property real maxMsgWidth: root.width - senderMargin - 2 * hPadding - avatarBlockWidth
|
||||
property bool bigMsg
|
||||
|
||||
// If the ListView attached properties are not available,
|
||||
// then the root delegate is likely a Loader.
|
||||
|
@ -86,11 +89,8 @@ Control {
|
|||
spacing: 0
|
||||
|
||||
TimestampInfo {
|
||||
id: timestampItem
|
||||
|
||||
id: dateItem
|
||||
showDay: root.showDay
|
||||
showTime: root.showTime
|
||||
formattedTime: root.formattedTime
|
||||
formattedDay: root.formattedDay
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.fillWidth: true
|
||||
|
@ -101,12 +101,10 @@ Control {
|
|||
id: usernameblock
|
||||
Layout.preferredHeight: (seq === MsgSeq.first || seq === MsgSeq.single) ? 10 : 0
|
||||
visible: !isReply
|
||||
Layout.topMargin: (seq === MsgSeq.first || seq === MsgSeq.single) && !isOutgoing && !root.showTime ? 20 : 0
|
||||
|
||||
Label {
|
||||
id: username
|
||||
text: UtilsAdapter.getBestNameForUri(CurrentAccount.id, Author)
|
||||
font.bold: true
|
||||
visible: (seq === MsgSeq.first || seq === MsgSeq.single) && !isOutgoing
|
||||
font.pointSize: JamiTheme.smallFontSize
|
||||
color: JamiTheme.chatviewSecondaryInformationColor
|
||||
|
@ -212,7 +210,7 @@ Control {
|
|||
RowLayout {
|
||||
id: msgRowlayout
|
||||
|
||||
Layout.preferredHeight: innerContent.height + root.extraHeight + (emojiReactions.emojis === "" ? 0 : emojiReactions.height - 8)
|
||||
Layout.preferredHeight: innerContent.height + root.extraHeight + (emojiReactions.emojis === "" ? 0 : emojiReactions.height - 8) + (IsEmojiOnly && (root.seq === MsgSeq.last || root.seq === MsgSeq.single) && emojiReactions.emojis === "" ? 15 : 0)
|
||||
Layout.topMargin: ((seq === MsgSeq.first || seq === MsgSeq.single) && !root.isReply) ? 6 : 0
|
||||
|
||||
Item {
|
||||
|
@ -238,19 +236,7 @@ Control {
|
|||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
MouseArea {
|
||||
id: bubbleArea
|
||||
|
||||
anchors.fill: bubble
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: function (mouse) {
|
||||
if (root.hoveredLink) {
|
||||
MessagesAdapter.openUrl(root.hoveredLink);
|
||||
}
|
||||
}
|
||||
property bool bubbleHovered: containsMouse || textHovered
|
||||
}
|
||||
|
||||
Column {
|
||||
id: innerContent
|
||||
|
@ -351,18 +337,93 @@ Control {
|
|||
id: bubble
|
||||
|
||||
property bool isEdited: PreviousBodies.length !== 0
|
||||
visible: !IsEmojiOnly
|
||||
z: -1
|
||||
out: isOutgoing
|
||||
type: seq
|
||||
isReply: root.isReply
|
||||
color: root.getBaseColor()
|
||||
color: IsEmojiOnly ? "transparent" : root.getBaseColor()
|
||||
radius: msgRadius
|
||||
anchors.right: isOutgoing ? parent.right : undefined
|
||||
anchors.top: parent.top
|
||||
|
||||
width: Type === Interaction.Type.TEXT && !isEdited ? root.textContentWidth : innerContent.childrenRect.width
|
||||
height: innerContent.childrenRect.height + (visible ? root.extraHeight : 0)
|
||||
property real timePosition: JamiTheme.emojiMargins + emojiReactions.width + 8
|
||||
property alias timestampItem: timestampItem
|
||||
|
||||
width: (Type === Interaction.Type.TEXT ? root.textContentWidth : innerContent.childrenRect.width)
|
||||
height: innerContent.childrenRect.height + (visible ? root.extraHeight : 0) + (root.bigMsg ? 15 : 0)
|
||||
|
||||
TimestampInfo {
|
||||
id: timestampItem
|
||||
|
||||
showTime: IsEmojiOnly && !(root.seq === MsgSeq.last || root.seq === MsgSeq.single) ? false : true
|
||||
formattedTime: root.formattedTime
|
||||
|
||||
timeColor: IsEmojiOnly ? (JamiTheme.darkTheme ? "white" : "dark") : (UtilsAdapter.luma(bubble.color) ? "white" : "dark")
|
||||
timeLabel.opacity: 0.5
|
||||
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: IsEmojiOnly ? (isOutgoing ? parent.right : undefined) : parent.right
|
||||
anchors.left: (IsEmojiOnly && !isOutgoing) ? parent.left : undefined
|
||||
anchors.leftMargin: (IsEmojiOnly && !isOutgoing && emojiReactions.visible) ? bubble.timePosition : 0
|
||||
anchors.rightMargin: IsEmojiOnly ? ((isOutgoing && emojiReactions.visible) ? bubble.timePosition : 0) : 10
|
||||
timeLabel.Layout.bottomMargin: {
|
||||
if (IsEmojiOnly)
|
||||
return -15;
|
||||
if (root.bigMsg)
|
||||
return 5;
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: editedRow
|
||||
anchors.left: root.bigMsg ? bubble.left : timestampItem.left
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: root.bigMsg ? 6 : 10
|
||||
anchors.leftMargin: root.bigMsg ? 10 : - timestampItem.width - 10
|
||||
visible: bubble.isEdited
|
||||
z: 1
|
||||
|
||||
ResponsiveImage {
|
||||
id: editedImage
|
||||
source: JamiResources.round_edit_24dp_svg
|
||||
width: 12
|
||||
height: 12
|
||||
color: editedLabel.color
|
||||
opacity: 0.5
|
||||
}
|
||||
|
||||
Text {
|
||||
id: editedLabel
|
||||
text: JamiStrings.edited
|
||||
color: UtilsAdapter.luma(bubble.color) ? "white" : "dark"
|
||||
opacity: 0.5
|
||||
font.pixelSize: JamiTheme.timestampFont
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onTapped: {
|
||||
viewCoordinator.presentDialog(appWindow, "commoncomponents/EditedPopup.qml", {
|
||||
"previousBodies": PreviousBodies
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: bubbleArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: function (mouse) {
|
||||
if (root.hoveredLink) {
|
||||
MessagesAdapter.openUrl(root.hoveredLink);
|
||||
}
|
||||
}
|
||||
property bool bubbleHovered: containsMouse || textHovered
|
||||
}
|
||||
}
|
||||
|
||||
EmojiReactions {
|
||||
|
@ -376,7 +437,7 @@ Control {
|
|||
borderColor: root.getBaseColor()
|
||||
maxWidth: 2 / 3 * maxMsgWidth - JamiTheme.emojiMargins
|
||||
|
||||
state: root.isOutgoing ? "anchorsRight" : (emojiReactions.width > bubble.width - JamiTheme.emojiMargins ? "anchorsLeft" : "anchorsRight")
|
||||
state: root.isOutgoing ? "anchorsRight" : (IsEmojiOnly ? "anchorsLeft" :(emojiReactions.width > bubble.width - JamiTheme.emojiMargins ? "anchorsLeft" : "anchorsRight"))
|
||||
|
||||
TapHandler {
|
||||
onTapped: {
|
||||
|
@ -519,7 +580,7 @@ Control {
|
|||
orientation: ListView.Horizontal
|
||||
Layout.preferredHeight: {
|
||||
if (showTime || seq === MsgSeq.last)
|
||||
return contentHeight + timestampItem.contentHeight;
|
||||
return contentHeight + dateItem.contentHeight;
|
||||
else if (readsMultiple.visible)
|
||||
return JamiTheme.avatarReadReceiptSize;
|
||||
return 0;
|
||||
|
|
|
@ -33,6 +33,8 @@ SBSMessageBase {
|
|||
property string colorUrl: UtilsAdapter.luma(bubble.color) ? JamiTheme.chatviewLinkColorLight : JamiTheme.chatviewLinkColorDark
|
||||
property string colorText: UtilsAdapter.luma(bubble.color) ? JamiTheme.chatviewTextColorLight : JamiTheme.chatviewTextColorDark
|
||||
|
||||
bigMsg: textEditId.lineCount > 1
|
||||
|
||||
Connections {
|
||||
target: bubble
|
||||
function onColorChanged(color) {
|
||||
|
@ -52,14 +54,14 @@ SBSMessageBase {
|
|||
formattedDay: MessagesAdapter.getFormattedDay(Timestamp)
|
||||
extraHeight: extraContent.active && !isRemoteImage ? msgRadius : -isRemoteImage
|
||||
textHovered: textHoverhandler.hovered
|
||||
textContentWidth: textEditId.width
|
||||
textContentWidth: textEditId.width + (bigMsg ? 0 : root.timeWidth + root.editedWidth)
|
||||
textContentHeight: textEditId.height
|
||||
|
||||
innerContent.children: [
|
||||
TextEdit {
|
||||
id: textEditId
|
||||
|
||||
padding: isEmojiOnly ? 0 : JamiTheme.preferredMarginSize
|
||||
padding: isEmojiOnly ? 0 : 10
|
||||
anchors.right: isOutgoing ? parent.right : undefined
|
||||
text: {
|
||||
if (Body !== "" && ParsedBody.length === 0) {
|
||||
|
@ -80,9 +82,11 @@ SBSMessageBase {
|
|||
else if (isEmojiOnly)
|
||||
Math.min((2 / 3) * root.maxMsgWidth, implicitWidth, innerContent.width - senderMargin - (innerContent.width - senderMargin) % (JamiTheme.chatviewEmojiSize + 2));
|
||||
else
|
||||
Math.min((2 / 3) * root.maxMsgWidth, implicitWidth, innerContent.width - senderMargin);
|
||||
Math.max(Math.min((2 / 3) * root.maxMsgWidth - ( bigMsg ? 0 : root.timeWidth + root.editedWidth), implicitWidth + 5, innerContent.width - senderMargin + 5), bigMsg ? root.timeWidth + root.editedWidth + 14: 0) ;
|
||||
}
|
||||
|
||||
anchors.rightMargin: bigMsg ? 0 : root.timeWidth + root.editedWidth
|
||||
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
selectByMouse: true
|
||||
font.pointSize: isEmojiOnly ? JamiTheme.chatviewEmojiSize : JamiTheme.mediumFontSize
|
||||
|
@ -126,48 +130,7 @@ SBSMessageBase {
|
|||
selectOnly: parent.readOnly
|
||||
}
|
||||
},
|
||||
RowLayout {
|
||||
id: editedRow
|
||||
|
||||
anchors.right: isOutgoing ? parent.right : undefined
|
||||
visible: PreviousBodies.length !== 0
|
||||
|
||||
ResponsiveImage {
|
||||
id: editedImage
|
||||
|
||||
Layout.leftMargin: JamiTheme.preferredMarginSize
|
||||
Layout.bottomMargin: JamiTheme.preferredMarginSize
|
||||
source: JamiResources.round_edit_24dp_svg
|
||||
width: JamiTheme.editedFontSize
|
||||
height: JamiTheme.editedFontSize
|
||||
layer {
|
||||
enabled: true
|
||||
effect: ColorOverlay {
|
||||
color: editedLabel.color
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: editedLabel
|
||||
|
||||
Layout.rightMargin: JamiTheme.preferredMarginSize
|
||||
Layout.bottomMargin: JamiTheme.preferredMarginSize
|
||||
|
||||
text: JamiStrings.edited
|
||||
color: root.colorText
|
||||
font.pointSize: JamiTheme.editedFontSize
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onTapped: {
|
||||
viewCoordinator.presentDialog(appWindow, "commoncomponents/EditedPopup.qml", {
|
||||
"previousBodies": PreviousBodies
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Loader {
|
||||
id: extraContent
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ ColumnLayout {
|
|||
property string formattedTime
|
||||
property string formattedDay
|
||||
property real detailsOpacity: 0.6
|
||||
property color timeColor: JamiTheme.chatviewSecondaryInformationColor
|
||||
property alias timeLabel: formattedTimeLabel
|
||||
|
||||
spacing: 0
|
||||
|
||||
|
@ -97,8 +99,8 @@ ColumnLayout {
|
|||
Layout.topMargin: 30
|
||||
Layout.bottomMargin: 30
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
color: JamiTheme.chatviewSecondaryInformationColor
|
||||
visible: showTime || showDay
|
||||
color: root.timeColor
|
||||
visible: showTime
|
||||
Layout.preferredHeight: visible * implicitHeight
|
||||
font.pointSize: JamiTheme.smallFontSize
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ JamiListView {
|
|||
function isFirst() {
|
||||
if (!nItem) return true
|
||||
else {
|
||||
if (item.showTime || item.isReply || nItem.isEmojiOnly ) {
|
||||
if (item.showTime || item.isReply ) {
|
||||
return true
|
||||
} else if (nItem.author !== item.author) {
|
||||
return true
|
||||
|
@ -121,7 +121,7 @@ JamiListView {
|
|||
function isLast() {
|
||||
if (!pItem) return true
|
||||
else {
|
||||
if (pItem.showTime || pItem.isReply || pItem.isEmojiOnly) {
|
||||
if (pItem.showTime || pItem.isReply) {
|
||||
return true
|
||||
} else if (pItem.author !== item.author) {
|
||||
return true
|
||||
|
|
|
@ -716,8 +716,7 @@ MessagesAdapter::getFormattedTime(const quint64 timestamp)
|
|||
auto curLocal = QLocale(curLang);
|
||||
auto curTime = QDateTime::fromSecsSinceEpoch(timestamp).time();
|
||||
QString timeLocale;
|
||||
timeLocale = curLocal.toString(curTime, curLocal.ShortFormat);
|
||||
|
||||
timeLocale = curLocal.toString(curTime, curLocal.ShortFormat).toLower();
|
||||
return timeLocale;
|
||||
}
|
||||
return QObject::tr("just now");
|
||||
|
|
Loading…
Add table
Reference in a new issue