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

219 lines
7.1 KiB
QML
Raw Normal View History

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
height: Math.max(imgProfile.height, rectMessageBubble.height)
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.leftMargin: calendarEvent ? 0 : 5
anchors.rightMargin: calendarEvent ? 0 : 9
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
}
Opaque.EllipsisLabel {
id: handle
visible: !fromMe && !calendarEvent
text: displayName
color: Theme.messageFromOtherTextColor
size: Theme.chatSize * gcd.themeScale
weight: Font.Bold
font.family: Fonts.applicationFontBold.name
font.styleName: "Bold"
leftPadding: 10 * gcd.themeScale
topPadding: 10 * gcd.themeScale
container: lbl
}
onWidthChanged: { handle.textResize() }
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 + "fontawesome/regular/window-close.svg" : (root.ackd ? gcd.assetPath + "fontawesome/regular/check-circle.svg" : gcd.assetPath + "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")
}
}
}
}