mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-08-02 05:45:59 +02:00
192 lines
5.8 KiB
QML
192 lines
5.8 KiB
QML
![]() |
import QtQuick 2.15
|
||
|
import QtQuick.Controls 2.15
|
||
|
import QtQuick.Layouts 1.15
|
||
|
import QtWebEngine 1.10
|
||
|
|
||
|
import net.jami.Models 1.1
|
||
|
import net.jami.Adapters 1.1
|
||
|
import net.jami.Constants 1.1
|
||
|
|
||
|
Control {
|
||
|
id: root
|
||
|
|
||
|
readonly property bool isGenerated: Type === Interaction.Type.CALL ||
|
||
|
Type === Interaction.Type.CONTACT
|
||
|
readonly property string author: Author
|
||
|
readonly property var timestamp: Timestamp
|
||
|
readonly property bool isOutgoing: model.Author === ""
|
||
|
readonly property var formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
|
||
|
readonly property bool isImage: MessagesAdapter.isImage(Body)
|
||
|
readonly property bool isAnimatedImage: MessagesAdapter.isAnimatedImage(Body)
|
||
|
readonly property var linkPreviewInfo: LinkPreviewInfo
|
||
|
|
||
|
readonly property var body: Body
|
||
|
readonly property real msgMargin: 64
|
||
|
|
||
|
width: parent ? parent.width : 0
|
||
|
height: loader.height
|
||
|
|
||
|
Loader {
|
||
|
id: loader
|
||
|
|
||
|
property alias isOutgoing: root.isOutgoing
|
||
|
property alias isGenerated: root.isGenerated
|
||
|
readonly property var author: Author
|
||
|
readonly property var body: Body
|
||
|
|
||
|
sourceComponent: isGenerated ?
|
||
|
generatedMsgComp :
|
||
|
userMsgComp
|
||
|
}
|
||
|
|
||
|
Component {
|
||
|
id: generatedMsgComp
|
||
|
|
||
|
Column {
|
||
|
width: root.width
|
||
|
spacing: 2
|
||
|
|
||
|
TextArea {
|
||
|
width: parent.width
|
||
|
text: body
|
||
|
horizontalAlignment: Qt.AlignHCenter
|
||
|
readOnly: true
|
||
|
font.pointSize: 11
|
||
|
color: JamiTheme.chatviewTextColor
|
||
|
}
|
||
|
|
||
|
Item {
|
||
|
id: infoCell
|
||
|
|
||
|
width: parent.width
|
||
|
height: childrenRect.height
|
||
|
|
||
|
Component.onCompleted: children = timestampLabel
|
||
|
}
|
||
|
|
||
|
bottomPadding: 12
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Component {
|
||
|
id: userMsgComp
|
||
|
|
||
|
GridLayout {
|
||
|
id: gridLayout
|
||
|
|
||
|
width: root.width
|
||
|
|
||
|
columns: 2
|
||
|
rows: 2
|
||
|
|
||
|
columnSpacing: 2
|
||
|
rowSpacing: 2
|
||
|
|
||
|
Column {
|
||
|
id: msgCell
|
||
|
|
||
|
Layout.column: isOutgoing ? 0 : 1
|
||
|
Layout.row: 0
|
||
|
Layout.fillWidth: true
|
||
|
Layout.maximumWidth: 640
|
||
|
Layout.preferredHeight: childrenRect.height
|
||
|
Layout.alignment: isOutgoing ? Qt.AlignRight : Qt.AlignLeft
|
||
|
Layout.leftMargin: isOutgoing ? msgMargin : 0
|
||
|
Layout.rightMargin: isOutgoing ? 0 : msgMargin
|
||
|
|
||
|
Control {
|
||
|
id: msgBlock
|
||
|
|
||
|
width: parent.width
|
||
|
|
||
|
contentItem: Column {
|
||
|
id: msgContent
|
||
|
|
||
|
property real txtWidth: ta.contentWidth + 3 * ta.padding
|
||
|
|
||
|
TextArea {
|
||
|
id: ta
|
||
|
width: parent.width
|
||
|
text: body
|
||
|
padding: 10
|
||
|
font.pointSize: 11
|
||
|
font.hintingPreference: Font.PreferNoHinting
|
||
|
renderType: Text.NativeRendering
|
||
|
textFormat: TextEdit.RichText
|
||
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||
|
transform: Translate { x: bg.x }
|
||
|
rightPadding: isOutgoing ? padding * 1.5 : 0
|
||
|
color: isOutgoing ?
|
||
|
JamiTheme.messageOutTxtColor :
|
||
|
JamiTheme.messageInTxtColor
|
||
|
}
|
||
|
}
|
||
|
background: Rectangle {
|
||
|
id: bg
|
||
|
|
||
|
anchors.right: isOutgoing ? msgContent.right : undefined
|
||
|
width: msgContent.txtWidth
|
||
|
radius: 18
|
||
|
color: isOutgoing ?
|
||
|
JamiTheme.messageOutBgColor :
|
||
|
JamiTheme.messageInBgColor
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
Item {
|
||
|
id: infoCell
|
||
|
|
||
|
Layout.column: isOutgoing ? 0 : 1
|
||
|
Layout.row: 1
|
||
|
Layout.fillWidth: true
|
||
|
Layout.preferredHeight: childrenRect.height
|
||
|
|
||
|
Component.onCompleted: children = timestampLabel
|
||
|
}
|
||
|
Item {
|
||
|
id: avatarCell
|
||
|
|
||
|
Layout.column: isOutgoing ? 1 : 0
|
||
|
Layout.row: 0
|
||
|
Layout.preferredWidth: isOutgoing ? 16 : avatar.width
|
||
|
Layout.preferredHeight: msgCell.height
|
||
|
Layout.leftMargin: isOutgoing ? 0 : 6
|
||
|
Layout.rightMargin: Layout.leftMargin
|
||
|
Avatar {
|
||
|
id: avatar
|
||
|
visible: !isOutgoing
|
||
|
anchors.bottom: parent.bottom
|
||
|
width: 32
|
||
|
height: 32
|
||
|
imageId: author
|
||
|
showPresenceIndicator: false
|
||
|
mode: Avatar.Mode.Contact
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Label {
|
||
|
id: timestampLabel
|
||
|
|
||
|
text: formattedTime
|
||
|
color: JamiTheme.timestampColor
|
||
|
|
||
|
anchors.right: isGenerated || !isOutgoing ? undefined : parent.right
|
||
|
anchors.rightMargin: 6
|
||
|
anchors.left: isGenerated || isOutgoing ? undefined : parent.left
|
||
|
anchors.leftMargin: 6
|
||
|
anchors.horizontalCenter: isGenerated ? parent.horizontalCenter : undefined
|
||
|
}
|
||
|
|
||
|
opacity: 0
|
||
|
Behavior on opacity { NumberAnimation { duration: 40 } }
|
||
|
|
||
|
Component.onCompleted: {
|
||
|
opacity = 1
|
||
|
if (!Linkified && !isImage && !isAnimatedImage) {
|
||
|
MessagesAdapter.parseMessageUrls(Id, Body)
|
||
|
}
|
||
|
}
|
||
|
}
|