2020-05-20 01:39:57 +00:00
|
|
|
import QtGraphicalEffects 1.0
|
|
|
|
import QtQuick 2.7
|
|
|
|
import QtQuick.Controls 2.4
|
|
|
|
import QtQuick.Controls.Material 2.0
|
|
|
|
import QtQuick.Layouts 1.3
|
|
|
|
|
2020-05-20 20:49:00 +00:00
|
|
|
import "../opaque" as Opaque
|
2020-05-20 02:39:01 +00:00
|
|
|
import "../opaque/controls" as Awesome
|
2020-07-25 16:47:19 +00:00
|
|
|
import "../opaque/theme"
|
|
|
|
import "../opaque/fonts"
|
2020-05-20 01:39:57 +00:00
|
|
|
|
2020-07-25 16:47:19 +00:00
|
|
|
Rectangle {
|
2020-05-20 01:39:57 +00:00
|
|
|
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
|
2020-07-25 16:47:19 +00:00
|
|
|
property int timestamp
|
2020-05-20 01:39:57 +00:00
|
|
|
property alias image: imgProfile.source
|
|
|
|
property string error
|
2020-07-25 16:47:19 +00:00
|
|
|
property bool calendarEvent
|
|
|
|
|
|
|
|
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
|
2020-05-20 01:39:57 +00:00
|
|
|
|
|
|
|
Connections {
|
|
|
|
target: gcd
|
|
|
|
|
|
|
|
onAcknowledged: function(mid) {
|
|
|
|
if (mid == messageID) {
|
|
|
|
root.ackd = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onGroupSendError: function(mid, error) {
|
|
|
|
if (mid == messageID) {
|
|
|
|
root.error = error
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-20 20:49:00 +00:00
|
|
|
Opaque.Portrait {
|
2020-05-20 01:39:57 +00:00
|
|
|
id: imgProfile
|
|
|
|
anchors.left: parent.left
|
2020-07-25 16:47:19 +00:00
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
|
|
|
|
visible: !fromMe && !calendarEvent
|
|
|
|
|
|
|
|
|
|
|
|
size: fromMe || calendarEvent ? 0 : Theme.contactPortraitSize * 0.5
|
|
|
|
badgeVisible: false
|
|
|
|
|
|
|
|
|
|
|
|
portraitBorderColor: Theme.portraitOnlineBorderColor
|
|
|
|
portraitColor: Theme.portraitOnlineBackgroundColor
|
2020-05-20 01:39:57 +00:00
|
|
|
|
|
|
|
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
|
2020-07-25 16:47:19 +00:00
|
|
|
height: (handle.visible ? handle.height : 0) + (10 * gcd.themeScale) + colMessageBubble.height + 8
|
2020-05-20 01:39:57 +00:00
|
|
|
width: colMessageBubble.width + 6
|
2020-07-25 16:47:19 +00:00
|
|
|
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
|
2020-05-20 01:39:57 +00:00
|
|
|
anchors.topMargin: 5
|
|
|
|
|
2020-07-25 16:47:19 +00:00
|
|
|
// 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
|
|
|
|
}
|
2020-05-20 01:39:57 +00:00
|
|
|
|
2020-07-25 16:47:19 +00:00
|
|
|
onWidthChanged: { handle.textResize() }
|
|
|
|
|
|
|
|
Column {
|
2020-05-20 01:39:57 +00:00
|
|
|
id: colMessageBubble
|
|
|
|
|
2020-07-25 16:47:19 +00:00
|
|
|
width: Math.max(lbl.width, ts.width + ack.width + 10)
|
2020-05-20 01:39:57 +00:00
|
|
|
|
2020-07-25 16:47:19 +00:00
|
|
|
anchors.top: fromMe ? parent.top : (calendarEvent ? parent.top : handle.bottom)
|
|
|
|
anchors.topMargin: 10 * gcd.themeScale
|
2020-05-20 01:39:57 +00:00
|
|
|
|
2020-07-25 16:47:19 +00:00
|
|
|
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
|
2020-05-20 01:39:57 +00:00
|
|
|
}
|
|
|
|
|
2020-07-25 16:47:19 +00:00
|
|
|
Row {
|
2020-05-20 01:39:57 +00:00
|
|
|
id: rowBottom
|
|
|
|
anchors.right: parent.right
|
2020-07-25 16:47:19 +00:00
|
|
|
visible: !calendarEvent
|
2020-05-20 01:39:57 +00:00
|
|
|
|
2020-07-25 16:47:19 +00:00
|
|
|
Opaque.ScalingLabel { // TIMESTAMP
|
2020-05-20 01:39:57 +00:00
|
|
|
id: ts
|
2020-07-25 16:47:19 +00:00
|
|
|
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
|
2020-05-20 01:39:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
2020-07-25 16:47:19 +00:00
|
|
|
height: Theme.chatMetaTextSize * gcd.themeScale
|
|
|
|
width: Theme.chatMetaTextSize * gcd.themeScale
|
|
|
|
anchors.bottom: parent.bottom
|
|
|
|
|
|
|
|
sourceSize.height: Theme.chatMetaTextSize * gcd.themeScale
|
2020-05-20 01:39:57 +00:00
|
|
|
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")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|