This repository has been archived on 2021-06-24. You can view files and clone it, but cannot push or open issues or pull requests.
ui/qml/widgets/Message.qml

218 lines
7.1 KiB
QML

import QtGraphicalEffects 1.0
import QtQuick 2.7
import QtQuick.Controls 2.4
import QtQuick.Controls.Material 2.0
import QtQuick.Layouts 1.3
import "../opaque" as Opaque
import "../opaque/controls" as Awesome
import "../opaque/theme"
import "../opaque/fonts"
Rectangle {
id: root
implicitHeight: Math.max(imgProfile.height, rectMessageBubble.height)
height: implicitHeight
color: Theme.backgroundMainColor
property string message
property string rawMessage
property string from
property string handle
property string displayName
property string messageID
property bool fromMe
property bool ackd
property int timestamp
property alias image: imgProfile.source
property string error
property bool calendarEvent
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
Connections {
target: gcd
onAcknowledged: function(mid) {
if (mid == messageID) {
root.ackd = true
}
}
onGroupSendError: function(mid, error) {
if (mid == messageID) {
root.error = error
}
}
}
Opaque.Portrait {
id: imgProfile
anchors.left: parent.left
anchors.bottom: parent.bottom
visible: !fromMe && !calendarEvent
size: fromMe || calendarEvent ? 0 : Theme.contactPortraitSize * 0.5
badgeVisible: false
portraitBorderColor: Theme.portraitOnlineBorderColor
portraitColor: Theme.portraitOnlineBackgroundColor
ToolTip.visible: ima.containsMouse
//: Click to DM
ToolTip.text: qsTr("dm-tooltip")
MouseArea {
id: ima
anchors.fill: parent
hoverEnabled: overlay.inGroup
onClicked: {
gcd.createContact(from)
gcd.broadcast("ResetMessagePane")
theStack.pane = theStack.messagePane
gcd.loadMessagesPane(from)
overlayStack.overlay = overlayStack.chatOverlay
}
}
}
Rectangle { // THIS IS JUST A PRETTY MESSAGE-HOLDING RECTANGLE
id: rectMessageBubble
height: (handle.visible ? handle.height : 0) + (10 * gcd.themeScale) + colMessageBubble.height + 8
width: colMessageBubble.width + 6
color: fromMe ? Theme.messageFromMeBackgroundColor : (calendarEvent ? Theme.messageFromOtherBackgroundColor : Theme.messageFromOtherBackgroundColor)
radius: 15 * logscale
anchors.left: fromMe ? undefined : (calendarEvent ? undefined : imgProfile.right) //parent.left
anchors.right: fromMe ? (calendarEvent ? undefined : parent.right) : undefined
anchors.horizontalCenter: calendarEvent ? parent.horizontalCenter : undefined
anchors.topMargin: 5
// A sharp corner on the side of the "speaker"
Rectangle {
id: sharpCorner
visible: !calendarEvent
height: parent.radius
width: parent.radius
anchors.bottom: rectMessageBubble.bottom
anchors.left: fromMe ? undefined : parent.left
anchors.right: fromMe ? parent.right : undefined
color: parent.color
}
Label {
id: handle
visible: !fromMe && !calendarEvent
text: displayName
color: Theme.messageFromOtherTextColor
elide: Text.ElideRight
width: parent.width - 20 // padding
font.pixelSize: Theme.chatSize * gcd.themeScale
font.weight: Font.Bold
font.family: Fonts.applicationFontBold.name
font.styleName: "Bold"
leftPadding: 10 * gcd.themeScale
topPadding: 10 * gcd.themeScale
}
Column {
id: colMessageBubble
width: Math.max(lbl.width, ts.width + ack.width + 10)
anchors.top: fromMe ? parent.top : (calendarEvent ? parent.top : handle.bottom)
anchors.topMargin: 10 * gcd.themeScale
TextEdit { // this is used as a helper to calculate the message box width
id: dummy
visible: false
padding: 6 * gcd.themeScale
leftPadding: 10 * gcd.themeScale
font.pixelSize: gcd.themeScale * Theme.chatSize
wrapMode: TextEdit.NoWrap
text: lbl.text
textFormat: Text.RichText
}
TextEdit { // this is the actual text display
id: lbl
text: parse(message, 12, true)
color: fromMe ? Theme.messageFromMeTextColor : Theme.messageFromOtherTextColor
padding: 6 * gcd.themeScale
leftPadding: 10 * gcd.themeScale
font.pixelSize: gcd.themeScale * Theme.chatSize
selectByMouse: gcd.os != "android"
readOnly: true
width: Math.min(dummy.width, root.parent.width - (imgProfile.visible ? imgProfile.width : 0) - 40)
wrapMode: TextEdit.Wrap
textFormat: Text.RichText
}
Row {
id: rowBottom
anchors.right: parent.right
visible: !calendarEvent
Opaque.ScalingLabel { // TIMESTAMP
id: ts
text: Qt.formatDateTime(new Date(root.timestamp*1000), "h:mm ap")
color: fromMe ? Theme.messageFromMeTextColor : Theme.messageFromOtherTextColor
font.pixelSize: Theme.chatMetaTextSize * gcd.themeScale
rightPadding: 10
}
Image { // ACKNOWLEDGEMENT ICON
id: ack
source: root.error != "" ? gcd.assetPath + "core/fontawesome/regular/window-close.webp" : (root.ackd ? gcd.assetPath + "core/fontawesome/regular/check-circle.webp" : gcd.assetPath + "core/fontawesome/regular/hourglass.svg")
height: Theme.chatMetaTextSize * gcd.themeScale
width: Theme.chatMetaTextSize * gcd.themeScale
anchors.bottom: parent.bottom
sourceSize.height: Theme.chatMetaTextSize * gcd.themeScale
visible: fromMe
ToolTip.visible: ma.containsMouse
ToolTip.delay: 200
//: Could not send this message
ToolTip.text: root.error != "" ? qsTr("could-not-send-msg-error") + ":" + root.error : (root.ackd ? qsTr("acknowledged-label") : qsTr("pending-label"))
MouseArea {
id: ma
anchors.fill: parent
hoverEnabled: true
}
}
}
}
TextEdit {
id: copyhelper
visible: false
text: root.rawMessage
}
MouseArea {
anchors.fill: gcd.os == "android" ? parent : null
onPressAndHold: {
copyhelper.selectAll()
copyhelper.copy()
gcd.popup("message copied")
}
}
}
}