// SPDX-FileCopyrightText: Nheko Contributors // // SPDX-License-Identifier: GPL-3.0-or-later import Qt.labs.platform 1.1 as Platform import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.2 import QtQuick.Window 2.13 import im.nheko 1.0 Column { required property var day required property bool isSender required property bool isStateEvent required property int parentWidth required property var previousMessageDay required property bool previousMessageIsStateEvent required property string previousMessageUserId required property date timestamp required property string userId required property string userName required property string userPowerlevel bottomPadding: Settings.bubbles ? (isSender && previousMessageDay == day ? 0 : 2) : 3 spacing: 8 topPadding: userName_.visible ? 4 : 0 visible: (previousMessageUserId !== userId || previousMessageDay !== day || isStateEvent !== previousMessageIsStateEvent) width: parentWidth Label { id: dateBubble anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined color: palette.text height: Math.round(fontMetrics.height * 1.4) horizontalAlignment: Text.AlignHCenter text: room ? room.formatDateSeparator(timestamp) : "" verticalAlignment: Text.AlignVCenter visible: room && previousMessageDay !== day width: contentWidth * 1.2 background: Rectangle { color: palette.window radius: parent.height / 2 } } Row { id: userInfo property int remainingWidth: chat.delegateMaxWidth - spacing - messageUserAvatar.width height: userName_.height spacing: 8 visible: !isStateEvent && (!isSender || !Settings.bubbles) Avatar { id: messageUserAvatar ToolTip.delay: Nheko.tooltipDelay ToolTip.text: userid ToolTip.visible: messageUserAvatar.hovered displayName: userName height: Nheko.avatarSize * (Settings.smallAvatars ? 0.5 : 1) url: !room ? "" : room.avatarUrl(userId).replace("mxc://", "image://MxcImage/") userid: userId width: Nheko.avatarSize * (Settings.smallAvatars ? 0.5 : 1) onClicked: room.openUserProfile(userId) } Connections { function onRoomAvatarUrlChanged() { messageUserAvatar.url = room.avatarUrl(userId).replace("mxc://", "image://MxcImage/"); } function onScrollToIndex(index) { chat.positionViewAtIndex(index, ListView.Center); } target: room } AbstractButton { id: userNameButton PowerlevelIndicator { id: powerlevelIndicator anchors.left: parent.left //anchors.horizontalCenter: parent.horizontalCenter powerlevel: userPowerlevel height: fontMetrics.lineSpacing width: fontMetrics.lineSpacing sourceSize.width: fontMetrics.lineSpacing sourceSize.height: fontMetrics.lineSpacing permissions: room ? room.permissions : null visible: isAdmin || isModerator } ToolTip.delay: Nheko.tooltipDelay ToolTip.text: userId ToolTip.visible: hovered leftPadding: powerlevelIndicator.visible ? 16 : 0 leftInset: 0 rightInset: 0 rightPadding: 0 contentItem: Label { id: userName_ color: TimelineManager.userColor(userId, palette.base) text: TimelineManager.escapeEmoji(userNameTextMetrics.elidedText) textFormat: Text.RichText } onClicked: room.openUserProfile(userId) TextMetrics { id: userNameTextMetrics elide: Text.ElideRight elideWidth: userInfo.remainingWidth - Math.min(statusMsg.implicitWidth, userInfo.remainingWidth / 3) text: userName } NhekoCursorShape { anchors.fill: parent cursorShape: Qt.PointingHandCursor } } Label { id: statusMsg property string userStatus: Presence.userStatus(userId) ToolTip.delay: Nheko.tooltipDelay ToolTip.text: qsTr("%1's status message").arg(userName) ToolTip.visible: statusMsgHoverHandler.hovered anchors.baseline: userNameButton.baseline color: palette.buttonText elide: Text.ElideRight font.italic: true font.pointSize: Math.floor(fontMetrics.font.pointSize * 0.8) text: userStatus.replace(/\n/g, " ") textFormat: Text.PlainText width: Math.min(implicitWidth, userInfo.remainingWidth - userName_.width - parent.spacing) HoverHandler { id: statusMsgHoverHandler } Connections { function onPresenceChanged(id) { if (id == userId) statusMsg.userStatus = Presence.userStatus(userId); } target: Presence } } } }