2021-03-05 02:35:15 +03:00
// SPDX-FileCopyrightText: 2021 Nheko Contributors
2022-01-01 06:57:53 +03:00
// SPDX-FileCopyrightText: 2022 Nheko Contributors
2021-03-07 07:57:56 +03:00
//
2021-03-05 02:35:15 +03:00
// SPDX-License-Identifier: GPL-3.0-or-later
2020-10-08 22:11:21 +03:00
import "./delegates"
import "./emoji"
2021-02-14 03:28:28 +03:00
import QtQuick 2.12
2019-10-17 10:36:16 +03:00
import QtQuick . Controls 2.3
2021-01-12 17:03:39 +03:00
import QtQuick . Layouts 1.2
2021-08-04 03:27:50 +03:00
import QtQuick . Window 2.13
2019-11-30 03:43:39 +03:00
import im . nheko 1.0
2019-10-08 21:55:09 +03:00
2020-07-26 03:06:38 +03:00
Item {
2021-07-12 01:24:33 +03:00
id: r
required property double proportionalHeight
required property int type
required property string typeString
required property int originalWidth
required property string blurhash
required property string body
required property string formattedBody
required property string eventId
required property string filename
required property string filesize
required property string url
required property string thumbnailUrl
required property bool isOnlyEmoji
required property bool isSender
required property bool isEncrypted
required property bool isEditable
required property bool isEdited
2022-02-07 23:00:51 +03:00
required property bool isStateEvent
2021-07-12 01:24:33 +03:00
required property string replyTo
required property string userId
required property string userName
2021-07-12 02:28:09 +03:00
required property string roomTopic
required property string roomName
required property string callType
2021-07-12 01:24:33 +03:00
required property var reactions
required property int trustlevel
2021-08-07 23:51:09 +03:00
required property int encryptionError
2021-07-12 01:24:33 +03:00
required property var timestamp
required property int status
2021-07-20 15:09:19 +03:00
required property int relatedEventCacheBuster
2021-07-12 01:24:33 +03:00
2020-10-08 22:11:21 +03:00
anchors.left: parent . left
anchors.right: parent . right
2022-02-12 00:02:30 +03:00
height: row . height + reactionRow . height
2020-10-08 22:11:21 +03:00
2021-01-18 22:49:40 +03:00
Rectangle {
2021-05-13 09:23:56 +03:00
color: ( Settings . messageHoverHighlight && hoverHandler . hovered ) ? Nheko.colors.alternateBase : "transparent"
2021-01-18 22:49:40 +03:00
anchors.fill: row
}
2021-02-14 03:28:28 +03:00
HoverHandler {
2021-01-18 22:49:40 +03:00
id: hoverHandler
2021-01-19 05:25:56 +03:00
2021-02-14 03:28:28 +03:00
acceptedDevices: PointerDevice . GenericPointer
}
TapHandler {
acceptedButtons: Qt . RightButton
2021-07-12 01:24:33 +03:00
onSingleTapped: messageContextMenu . show ( eventId , type , isSender , isEncrypted , isEditable , contentItem . child . hoveredLink , contentItem . child . copyText )
2021-04-11 23:24:39 +03:00
gesturePolicy: TapHandler . ReleaseWithinBounds
2021-02-14 03:28:28 +03:00
}
TapHandler {
2021-07-12 01:24:33 +03:00
onLongPressed: messageContextMenu . show ( eventId , type , isSender , isEncrypted , isEditable , contentItem . child . hoveredLink , contentItem . child . copyText )
onDoubleTapped: chat . model . reply = eventId
2021-04-11 23:24:39 +03:00
gesturePolicy: TapHandler . ReleaseWithinBounds
2020-10-08 22:11:21 +03:00
}
2022-02-05 23:53:21 +03:00
Control {
2020-10-08 22:11:21 +03:00
id: row
2021-03-05 18:47:20 +03:00
anchors.rightMargin: 1
2022-02-05 23:53:21 +03:00
anchors.leftMargin: Nheko . avatarSize + 12 // align bubble with section header
2020-10-08 22:11:21 +03:00
anchors.left: parent . left
2022-02-09 19:53:02 +03:00
property int maxWidth: parent . width - anchors . leftMargin - anchors . rightMargin
2022-02-12 00:02:30 +03:00
width: Settings . bubbles ? Math . min ( maxWidth , implicitWidth + metadata . width ) : maxWidth
padding: isStateEvent ? 0 : 3
2022-02-05 23:53:21 +03:00
background: Rectangle {
2022-02-05 01:12:30 +03:00
property color userColor: TimelineManager . userColor ( userId , Nheko . colors . base )
property color bgColor: Nheko . colors . base
2022-02-12 00:02:30 +03:00
color: Qt . tint ( bgColor , Qt . rgba ( userColor . r , userColor . g , userColor . b , 0.2 ) )
radius: parent . padding * 2
2022-02-07 23:00:51 +03:00
visible: Settings . bubbles && ! isStateEvent
2022-02-05 01:12:30 +03:00
}
2022-02-12 00:02:30 +03:00
contentItem: GridLayout {
2022-02-03 22:26:20 +03:00
id: msg
2022-02-09 23:36:04 +03:00
property bool narrowLayout: Settings . bubbles //&& (timelineView.width < 500) // timelineView causes fewew binding loops than r. But maybe it shouldn't depend on width anyway
2022-02-03 22:26:20 +03:00
rowSpacing: 0
2022-02-05 23:53:21 +03:00
columnSpacing: 2
2022-02-05 16:12:51 +03:00
columns: narrowLayout ? 1 : 2
rows: narrowLayout ? 3 : 2
2020-10-08 22:11:21 +03:00
// fancy reply, if this is a reply
Reply {
2022-02-03 22:26:20 +03:00
Layout.row: 0
Layout.column: 0
Layout.fillWidth: true
2022-02-05 23:53:21 +03:00
Layout.bottomMargin: visible ? 2 : 0
2022-02-12 00:02:30 +03:00
Layout.preferredHeight: height
Layout.maximumWidth: implicitWidth
2022-02-03 22:26:20 +03:00
id: reply
2021-07-12 23:28:01 +03:00
function fromModel ( role ) {
2021-07-16 12:47:49 +03:00
return replyTo != "" ? room . dataById ( replyTo , role , r . eventId ) : null ;
2021-07-12 23:28:01 +03:00
}
2021-07-12 01:24:33 +03:00
visible: replyTo
2021-07-20 15:09:19 +03:00
userColor: r . relatedEventCacheBuster , TimelineManager . userColor ( userId , Nheko . colors . base )
blurhash: r . relatedEventCacheBuster , fromModel ( Room . Blurhash ) ? ? ""
body: r . relatedEventCacheBuster , fromModel ( Room . Body ) ? ? ""
formattedBody: r . relatedEventCacheBuster , fromModel ( Room . FormattedBody ) ? ? ""
2021-07-12 23:28:01 +03:00
eventId: fromModel ( Room . EventId ) ? ? ""
2021-07-20 15:09:19 +03:00
filename: r . relatedEventCacheBuster , fromModel ( Room . Filename ) ? ? ""
filesize: r . relatedEventCacheBuster , fromModel ( Room . Filesize ) ? ? ""
proportionalHeight: r . relatedEventCacheBuster , fromModel ( Room . ProportionalHeight ) ? ? 1
type: r . relatedEventCacheBuster , fromModel ( Room . Type ) ? ? MtxEvent . UnknownMessage
typeString: r . relatedEventCacheBuster , fromModel ( Room . TypeString ) ? ? ""
url: r . relatedEventCacheBuster , fromModel ( Room . Url ) ? ? ""
originalWidth: r . relatedEventCacheBuster , fromModel ( Room . OriginalWidth ) ? ? 0
isOnlyEmoji: r . relatedEventCacheBuster , fromModel ( Room . IsOnlyEmoji ) ? ? false
2022-02-07 23:00:51 +03:00
isStateEvent: r . relatedEventCacheBuster , fromModel ( Room . IsStateEvent ) ? ? false
2021-07-20 15:09:19 +03:00
userId: r . relatedEventCacheBuster , fromModel ( Room . UserId ) ? ? ""
userName: r . relatedEventCacheBuster , fromModel ( Room . UserName ) ? ? ""
thumbnailUrl: r . relatedEventCacheBuster , fromModel ( Room . ThumbnailUrl ) ? ? ""
roomTopic: r . relatedEventCacheBuster , fromModel ( Room . RoomTopic ) ? ? ""
roomName: r . relatedEventCacheBuster , fromModel ( Room . RoomName ) ? ? ""
callType: r . relatedEventCacheBuster , fromModel ( Room . CallType ) ? ? ""
2021-08-07 23:51:09 +03:00
encryptionError: r . relatedEventCacheBuster , fromModel ( Room . EncryptionError ) ? ? ""
2021-07-20 15:09:19 +03:00
relatedEventCacheBuster: r . relatedEventCacheBuster , fromModel ( Room . RelatedEventCacheBuster ) ? ? 0
2020-10-08 22:11:21 +03:00
}
// actual message content
MessageDelegate {
2022-02-03 22:26:20 +03:00
Layout.row: 1
Layout.column: 0
Layout.fillWidth: true
2022-02-12 00:02:30 +03:00
Layout.preferredHeight: height
Layout.maximumWidth: implicitWidth
2020-10-08 22:11:21 +03:00
id: contentItem
2021-07-12 01:24:33 +03:00
blurhash: r . blurhash
body: r . body
formattedBody: r . formattedBody
eventId: r . eventId
filename: r . filename
filesize: r . filesize
proportionalHeight: r . proportionalHeight
type: r . type
typeString: r . typeString ? ? ""
url: r . url
thumbnailUrl: r . thumbnailUrl
originalWidth: r . originalWidth
isOnlyEmoji: r . isOnlyEmoji
2022-02-07 23:00:51 +03:00
isStateEvent: r . isStateEvent
2021-07-12 01:24:33 +03:00
userId: r . userId
userName: r . userName
2021-07-12 02:28:09 +03:00
roomTopic: r . roomTopic
roomName: r . roomName
callType: r . callType
2021-08-07 23:51:09 +03:00
encryptionError: r . encryptionError
2021-07-20 15:09:19 +03:00
relatedEventCacheBuster: r . relatedEventCacheBuster
2021-07-12 01:24:33 +03:00
isReply: false
2020-10-08 22:11:21 +03:00
}
2022-02-03 22:26:20 +03:00
RowLayout {
2022-02-09 19:53:02 +03:00
id: metadata
2022-02-05 16:12:51 +03:00
Layout.column: msg . narrowLayout ? 0 : 1
Layout.row: msg . narrowLayout ? 2 : 0
Layout.rowSpan: msg . narrowLayout ? 1 : 2
2022-02-12 00:02:30 +03:00
Layout.bottomMargin: - 4
2022-02-03 22:26:20 +03:00
Layout.alignment: Qt . AlignTop | Qt . AlignRight
2022-02-09 19:53:02 +03:00
Layout.preferredWidth: implicitWidth
2022-02-07 23:00:51 +03:00
visible: ! isStateEvent
2022-02-05 23:53:21 +03:00
2022-02-05 16:12:51 +03:00
property double scaling: msg . narrowLayout ? 0.75 : 1
2022-02-09 19:53:02 +03:00
2022-02-03 22:26:20 +03:00
StatusIndicator {
Layout.alignment: Qt . AlignRight | Qt . AlignTop
2022-02-05 16:12:51 +03:00
Layout.preferredHeight: 16 * parent . scaling
2022-02-09 19:53:02 +03:00
Layout.preferredWidth: 16 * parent . scaling
2022-02-03 22:26:20 +03:00
status: r . status
eventId: r . eventId
}
2020-10-08 22:11:21 +03:00
2022-02-03 22:26:20 +03:00
Image {
visible: isEdited || eventId == chat . model . edit
Layout.alignment: Qt . AlignRight | Qt . AlignTop
2022-02-05 16:12:51 +03:00
Layout.preferredHeight: 16 * parent . scaling
Layout.preferredWidth: 16 * parent . scaling
sourceSize.width: 16 * Screen . devicePixelRatio * parent . scaling
sourceSize.height: 16 * Screen . devicePixelRatio * parent . scaling
2022-02-03 22:26:20 +03:00
source: "image://colorimage/:/icons/icons/ui/edit.svg?" + ( ( eventId == chat . model . edit ) ? Nheko.colors.highlight : Nheko . colors . buttonText )
ToolTip.visible: editHovered . hovered
ToolTip.delay: Nheko . tooltipDelay
ToolTip.text: qsTr ( "Edited" )
HoverHandler {
id: editHovered
}
2020-10-08 22:11:21 +03:00
2022-02-03 22:26:20 +03:00
}
2020-10-08 22:11:21 +03:00
2022-02-03 22:26:20 +03:00
EncryptionIndicator {
visible: room . isEncrypted
encrypted: isEncrypted
trust: trustlevel
Layout.alignment: Qt . AlignRight | Qt . AlignTop
2022-02-05 16:12:51 +03:00
Layout.preferredHeight: 16 * parent . scaling
Layout.preferredWidth: 16 * parent . scaling
2022-02-09 19:53:02 +03:00
sourceSize.width: 16 * Screen . devicePixelRatio * parent . scaling
sourceSize.height: 16 * Screen . devicePixelRatio * parent . scaling
2022-02-03 22:26:20 +03:00
}
2020-10-08 22:11:21 +03:00
2022-02-03 22:26:20 +03:00
Label {
Layout.alignment: Qt . AlignRight | Qt . AlignTop
2022-02-09 19:53:02 +03:00
Layout.preferredWidth: implicitWidth
2022-02-03 22:26:20 +03:00
text: timestamp . toLocaleTimeString ( Locale . ShortFormat )
color: Nheko . inactiveColors . text
ToolTip.visible: ma . hovered
ToolTip.delay: Nheko . tooltipDelay
ToolTip.text: Qt . formatDateTime ( timestamp , Qt . DefaultLocaleLongDate )
2022-02-05 16:12:51 +03:00
font.pointSize: 10 * parent . scaling
2022-02-03 22:26:20 +03:00
HoverHandler {
id: ma
}
2020-10-08 22:11:21 +03:00
2022-02-03 22:26:20 +03:00
}
}
2021-11-11 06:43:37 +03:00
}
2022-02-05 23:53:21 +03:00
}
Reactions {
anchors {
top: row . bottom
left: parent . left
leftMargin: Nheko . avatarSize + 16
}
2021-11-11 06:43:37 +03:00
2022-02-05 23:53:21 +03:00
id: reactionRow
2020-10-08 22:11:21 +03:00
2022-02-05 23:53:21 +03:00
reactions: r . reactions
eventId: r . eventId
2020-10-08 22:11:21 +03:00
}
2019-10-08 21:55:09 +03:00
}