summary refs log tree commit diff
path: root/resources
diff options
context:
space:
mode:
Diffstat (limited to 'resources')
-rw-r--r--resources/qml/MatrixText.qml32
-rw-r--r--resources/qml/MessageView.qml148
-rw-r--r--resources/qml/delegates/TextMessage.qml15
3 files changed, 164 insertions, 31 deletions
diff --git a/resources/qml/MatrixText.qml b/resources/qml/MatrixText.qml
index 94b8bb98..de15e078 100644
--- a/resources/qml/MatrixText.qml
+++ b/resources/qml/MatrixText.qml
@@ -2,24 +2,24 @@
 //
 // SPDX-License-Identifier: GPL-3.0-or-later
 
-import QtQuick 2.5
-import QtQuick.Controls 2.3
-import im.nheko 1.0
+import QtQuick
+import QtQuick.Controls
+import im.nheko
 
-TextEdit {
+TextArea {
     id: r
 
     property alias cursorShape: cs.cursorShape
 
-    //leftInset: 0
-    //bottomInset: 0
-    //rightInset: 0
-    //topInset: 0
-    //leftPadding: 0
-    //bottomPadding: 0
-    //rightPadding: 0
-    //topPadding: 0
-    //background: null
+    leftInset: 0
+    bottomInset: 0
+    rightInset: 0
+    topInset: 0
+    leftPadding: 0
+    bottomPadding: 0
+    rightPadding: 0
+    topPadding: 0
+    background: null
 
     ToolTip.text: hoveredLink
     ToolTip.visible: hoveredLink || false
@@ -39,9 +39,9 @@ TextEdit {
     }
     onLinkActivated: Nheko.openLink(link)
 
-    //// propagate events up
-    //onPressAndHold: (event) => event.accepted = false
-    //onPressed: (event) => event.accepted = (event.button == Qt.LeftButton)
+    // propagate events up
+    onPressAndHold: (event) => event.accepted = false
+    onPressed: (event) => event.accepted = (event.button == Qt.LeftButton)
 
     NhekoCursorShape {
         id: cs
diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml
index fde7ee57..2852e5f7 100644
--- a/resources/qml/MessageView.qml
+++ b/resources/qml/MessageView.qml
@@ -63,28 +63,160 @@ Item {
             id: wrapper
             ListView.delayRemove: true
             width: chat.delegateMaxWidth
-            height: main?.height ?? 10
+            height: Math.max((section.item?.height ?? 0) + gridContainer.implicitHeight, 10)
+            anchors.horizontalCenter: ListView.view.contentItem.horizontalCenter
             room: chatRoot.roommodel
 
+            required property var day
+            required property bool isSender
+            required property bool isStateEvent
+            //required property var previousMessageDay
+            //required property bool previousMessageIsStateEvent
+            //required property string previousMessageUserId
+            required property int index
+            property var previousMessageDay: (index + 1) >= chat.count ? 0 : chat.model.dataByIndex(index + 1, Room.Day)
+            property bool previousMessageIsStateEvent: (index + 1) >= chat.count ? true : chat.model.dataByIndex(index + 1, Room.IsStateEvent)
+            property string previousMessageUserId: (index + 1) >= chat.count ? "" : chat.model.dataByIndex(index + 1, Room.UserId)
+            required property date timestamp
+            required property string userId
+            required property string userName
+            required property string threadId
+
+            data: [
+            Loader {
+                id: section
+
+                property var day: wrapper.day
+                property bool isSender: wrapper.isSender
+                property bool isStateEvent: wrapper.isStateEvent
+                property int parentWidth: wrapper.width
+                property var previousMessageDay: wrapper.previousMessageDay
+                property bool previousMessageIsStateEvent: wrapper.previousMessageIsStateEvent
+                property string previousMessageUserId: wrapper.previousMessageUserId
+                property date timestamp: wrapper.timestamp
+                property string userId: wrapper.userId
+                property string userName: wrapper.userName
+
+                active: previousMessageUserId !== userId || previousMessageDay !== day || previousMessageIsStateEvent !== isStateEvent
+                //asynchronous: true
+                sourceComponent: sectionHeader
+                visible: status == Loader.Ready
+                z: 4
+            }, 
+                GridLayout {
+                    id: gridContainer
+
+                    width: wrapper.width
+                    y: section.visible && section.active ? section.y + section.height : 0
+
+                    ColumnLayout {
+                        id: contentColumn
+                        Layout.fillWidth: true
+                        Layout.leftMargin: (wrapper.isStateEvent || Settings.smallAvatars ? 0 : (Nheko.avatarSize + 8)) + (wrapper.threadId ? 6 : 0) // align bubble with section header
+
+                        AbstractButton {
+                            id: replyRow
+                            visible: wrapper.reply
+                            Layout.fillWidth: true
+                            Layout.maximumHeight: timelineView.height / 8
+                            Layout.preferredWidth: replyRowLay.implicitWidth
+                            Layout.preferredHeight: replyRowLay.implicitHeight
+
+                            property color userColor: TimelineManager.userColor(wrapper.reply?.userId ?? '', palette.base)
+
+                            clip: true
+
+                            contentItem: RowLayout {
+                                id: replyRowLay
+
+                                anchors.fill: parent
+
+
+                                Rectangle {
+                                    id: replyLine
+                                    Layout.fillHeight: true
+                                    color: replyRow.userColor
+                                    Layout.preferredWidth: 4
+                                }
+
+                                ColumnLayout {
+                                    AbstractButton {
+                                        id: replyUserButton
+                                        Layout.fillWidth: true
+                                        contentItem: ElidedLabel {
+                                            id: userName_
+                                            fullText: wrapper.reply?.userName ?? ''
+                                            color: replyRow.userColor
+                                            textFormat: Text.RichText
+                                            width: parent.width
+                                            elideWidth: width
+                                        }
+                                        onClicked: room.openUserProfile(wrapper.reply?.userId)
+                                    }
+                                    data: [
+                                        replyUserButton,
+                                        wrapper.reply,
+                                    ]
+                                }
+                            }
+
+                            background: Rectangle {
+                                width: replyRow.implicitContentWidth
+                                color: Qt.tint(palette.base, Qt.hsla(replyRow.userColor.hslHue, 0.5, replyRow.userColor.hslLightness, 0.1))
+                            }
+                        }
+
+                        data: [
+                            replyRow, wrapper.main,
+                        ]
+                    }
+
+                    Rectangle {
+                        color: 'yellow'
+                        Layout.preferredWidth: 100
+                        Layout.preferredHeight: 20
+                        Layout.alignment: Qt.AlignRight | Qt.AlignTop
+                    }
+                },
+
+                Rectangle {
+                    width: Math.min(contentColumn.implicitWidth, contentColumn.width)
+                    height: contentColumn.implicitHeight
+                    color: "blue"
+                    opacity: 0.2
+                }
+            ]
+
             EventDelegateChoice {
                 roleValues: [
                     MtxEvent.TextMessage,
                     MtxEvent.NoticeMessage,
                 ]
-                TextArea {
-                    required property string body
+                TextMessage {
+                    id: textMes
+
+                    keepFullText: true
+                    required property string userId
+                    required property string userName
+
+                    Layout.fillWidth: true
+                    //Layout.maximumWidth: implicitWidth
 
-                    width: parent.width
-                    text: body
                 }
             }
 
             EventDelegateChoice {
                 roleValues: [
                 ]
-                TextArea {
-                    width: parent.width
-                    text: "Unsupported"
+                MatrixText {
+                    Layout.fillWidth: true
+
+                    required property string typeString
+
+                    text: "Unsupported: " + typeString
+
+                    required property string userId
+                    required property string userName
                 }
             }
         }
diff --git a/resources/qml/delegates/TextMessage.qml b/resources/qml/delegates/TextMessage.qml
index 1eb5e2c0..d4b72965 100644
--- a/resources/qml/delegates/TextMessage.qml
+++ b/resources/qml/delegates/TextMessage.qml
@@ -3,17 +3,19 @@
 // SPDX-License-Identifier: GPL-3.0-or-later
 
 import ".."
-import QtQuick.Controls 2.3
-import im.nheko 1.0
+import QtQuick.Controls
+import QtQuick.Layouts
+import im.nheko
 
 MatrixText {
     required property string body
     required property bool isOnlyEmoji
     required property bool isReply
     required property bool keepFullText
-    required property string formatted
+    required property string formattedBody
+
     property string copyText: selectedText ? getText(selectionStart, selectionEnd) : body
-    property int metadataWidth
+    property int metadataWidth: 100
     property bool fitsMetadata: false //positionAt(width,height-4) == positionAt(width-metadataWidth-10, height-4)
 
     // table border-collapse doesn't seem to work
@@ -38,9 +40,8 @@ MatrixText {
         background-color: " + palette.text + ";
     }" : "") +  // TODO(Nico): Figure out how to support mobile
     "</style>
-    " + formatted.replace(/<del>/g, "<s>").replace(/<\/del>/g, "</s>").replace(/<strike>/g, "<s>").replace(/<\/strike>/g, "</s>")
-    width: parent?.width ?? 0
-    height: !keepFullText ? Math.round(Math.min(timelineView.height / 8, implicitHeight)) : implicitHeight
+    " + formattedBody.replace(/<del>/g, "<s>").replace(/<\/del>/g, "</s>").replace(/<strike>/g, "<s>").replace(/<\/strike>/g, "</s>")
+    Layout.maximumHeight: !keepFullText ? Math.round(Math.min(timelineView.height / 8, implicitHeight)) : implicitHeight
     clip: !keepFullText
     selectByMouse: !Settings.mobileMode && !isReply
     enabled: !Settings.mobileMode