// SPDX-License-Identifier: LGPL-3.0-or-later import QtQuick 2.12 import QtQuick.Layouts 1.12 import "../../../Base" import "../../.." HRowLayout { id: eventContent spacing: theme.chat.message.horizontalSpacing layoutDirection: onRight ? Qt.RightToLeft: Qt.LeftToRight readonly property var mentions: JSON.parse(model.mentions) readonly property string mentionsCSS: { const lines = [] for (const [name, link] of mentions) { if (! link.match(/^https?:\/\/matrix.to\/#\/@.+/)) continue lines.push( `.mention[data-mention='${name}'] { color: ` + utils.nameColor(name) + "}" ) } return "" } readonly property string senderText: hideNameLine ? "" : ( `<${smallAvatar ? "span" : "div"} class='sender'>` + utils.coloredNameHtml(model.sender_name, model.sender_id) + (smallAvatar ? ": " : "") + (smallAvatar ? "" : "") ) property string contentText: utils.processedEventText(model) readonly property string timeText: utils.formatTime(model.date, false) readonly property string localEchoText: model.is_local_echo ? ` ` : "" readonly property bool pureMedia: ! contentText && linksRepeater.count readonly property string hoveredLink: contentLabel.hoveredLink readonly property bool hoveredSelectable: contentHover.hovered readonly property int xOffset: onRight ? Math.min( contentColumn.width - contentLabel.paintedWidth - contentLabel.leftPadding - contentLabel.rightPadding, contentColumn.width - linksRepeater.widestChild - ( pureMedia ? 0 : contentLabel.leftPadding + contentLabel.rightPadding ), ) : 0 readonly property int maxMessageWidth: contentText.includes("
") ?
        -1 :
        window.settings.maxMessageCharactersPerLine < 0 ?
        -1 :
        Math.ceil(
            mainUI.fontMetrics.averageCharacterWidth *
            window.settings.maxMessageCharactersPerLine
        )

    readonly property alias selectedText: contentLabel.selectedText


    Item {
        id: avatarWrapper
        opacity: collapseAvatar ? 0 : 1
        visible: ! hideAvatar

        Layout.minimumWidth:
            smallAvatar ?
            theme.chat.message.collapsedAvatarSize :
            theme.chat.message.avatarSize

        Layout.minimumHeight: collapseAvatar ? 1 : Layout.minimumWidth

        Layout.maximumWidth: Layout.minimumWidth
        Layout.maximumHeight: Layout.minimumHeight
        Layout.alignment: Qt.AlignTop

        HUserAvatar {
            id: avatar
            userId: model.sender_id
            displayName: model.sender_name
            mxc: model.sender_avatar
            width: parent.width
            height: collapseAvatar ? 1 : parent.Layout.minimumWidth
            radius: theme.chat.message.avatarRadius
        }
    }

    HColumnLayout {
        id: contentColumn

        Layout.fillWidth: true
        Layout.alignment: Qt.AlignVCenter

        HSelectableLabel {
            id: contentLabel
            visible: ! pureMedia
            enableLinkActivation: ! eventList.selectedCount

            selectByMouse:
                eventList.selectedCount <= 1 &&
                eventDelegate.checked &&
                textSelectionBlocker.point.scenePosition === Qt.point(0, 0)

            topPadding: theme.chat.message.verticalSpacing
            bottomPadding: topPadding
            leftPadding: eventContent.spacing
            rightPadding: leftPadding

            color: model.event_type === "RoomMessageNotice" ?
                   theme.chat.message.noticeBody :
                   theme.chat.message.body

            font.italic: model.event_type === "RoomMessageEmote"
            wrapMode: TextEdit.Wrap
            textFormat: Text.RichText
            text:
                // CSS
                theme.chat.message.styleInclude + mentionsCSS +

                // Sender name & message body
                (
                    smallAvatar && contentText.match(/^\s*<(p|h[1-6])>/) ?
                    contentText.replace(
                        /(^\s*<(p|h[1-6])>)/, "$1" + senderText,
                    ) :
                    senderText + contentText
                ) +

                // Time
                // For some reason, if there's only one space,
                // times will be on their own lines most of the time.
                "  " +
                `` +
                timeText +
                "" +

                // Local echo icon
                (model.is_local_echo ?
                 ` ` : "")

            transform: Translate { x: xOffset }

            Layout.maximumWidth: eventContent.maxMessageWidth
            Layout.fillWidth: true

            onSelectedTextChanged: if (selectedText) {
                eventList.delegateWithSelectedText = model.id
                eventList.selectedText             = selectedText
            } else if (eventList.delegateWithSelectedText === model.id) {
                eventList.delegateWithSelectedText = ""
                eventList.selectedText             = ""
            }

            Connections {
                target: eventList

                function onCheckedChanged() {
                    contentLabel.deselect()
                }

                function onDelegateWithSelectedTextChanged() {
                    if (eventList.delegateWithSelectedText !== model.id)
                        contentLabel.deselect()
                }
            }

            HoverHandler { id: contentHover }

            PointHandler {
                id: mousePointHandler
                acceptedButtons: Qt.LeftButton
                acceptedModifiers: Qt.NoModifier
                acceptedPointerTypes:
                    PointerDevice.GenericPointer | PointerDevice.Eraser

                onActiveChanged: {
                    if (active &&
                            ! eventDelegate.checked &&
                            (! parent.hoveredLink ||
                            ! parent.enableLinkActivation)) {

                        eventList.check(model.index)
                        checkedNow = true
                    }

                    if (! active && eventDelegate.checked) {
                        checkedNow ?
                        checkedNow = false :
                        eventList.uncheck(model.index)
                    }
                }

                property bool checkedNow: false
            }

            PointHandler {
                id: mouseShiftPointHandler
                acceptedButtons: Qt.LeftButton
                acceptedModifiers: Qt.ShiftModifier
                acceptedPointerTypes:
                    PointerDevice.GenericPointer | PointerDevice.Eraser

                onActiveChanged: {
                    if (active &&
                            ! eventDelegate.checked &&
                            (! parent.hoveredLink ||
                            ! parent.enableLinkActivation)) {

                        eventList.checkFromLastToHere(model.index)
                    }
                }
            }

            TapHandler {
                id: touchTapHandler
                acceptedButtons: Qt.LeftButton
                acceptedPointerTypes: PointerDevice.Finger | PointerDevice.Pen
                onTapped:
                    if (! parent.hoveredLink || ! parent.enableLinkActivation)
                        eventDelegate.toggleChecked()
            }

            TapHandler {
                id: textSelectionBlocker
                acceptedPointerTypes: PointerDevice.Finger | PointerDevice.Pen
            }

            Rectangle {
                id: contentBackground
                width: Math.max(
                    parent.paintedWidth +
                    parent.leftPadding + parent.rightPadding,

                    linksRepeater.summedWidth +
                    (pureMedia ? 0 : parent.leftPadding + parent.rightPadding),
                )
                height: contentColumn.height
                radius: theme.chat.message.radius
                z: -100
                color: eventDelegate.checked &&
                       ! contentLabel.selectedText &&
                       ! mousePointHandler.active &&
                       ! mouseShiftPointHandler.active ?
                       theme.chat.message.checkedBackground :

                       isOwn?
                       theme.chat.message.ownBackground :

                       theme.chat.message.background

                Behavior on color { HColorAnimation {} }

                Rectangle {
                    visible: model.event_type === "RoomMessageNotice"
                    // y: parent.height / 2 - height / 2
                    width: theme.chat.message.noticeLineWidth
                    height: parent.height
                    radius: parent.radius
                    color: utils.nameColor(
                        model.sender_name || model.sender_id.substring(1),
                    )
                }
            }
        }

        HRepeater {
            id: linksRepeater
            model: {
                const links = JSON.parse(eventDelegate.currentModel.links)

                if (eventDelegate.currentModel.media_url)
                    links.push(eventDelegate.currentModel.media_url)

                return links
            }

            EventMediaLoader {
                singleMediaInfo: eventDelegate.currentModel
                mediaUrl: modelData
                showSender: pureMedia ? senderText : ""
                showDate: pureMedia ? timeText : ""
                showLocalEcho: pureMedia ? localEchoText : ""

                transform: Translate { x: xOffset }

                Layout.bottomMargin: pureMedia ? 0 : contentLabel.bottomPadding
                Layout.leftMargin: pureMedia ? 0 : eventContent.spacing
                Layout.rightMargin: pureMedia ? 0 : eventContent.spacing
                Layout.preferredWidth: item ? item.width : -1
                Layout.preferredHeight: item ? item.height : -1
            }
        }
    }

    HSpacer {}
}