Message attached property
Create Message attached property to propagate parameters like room, timeline, index and maxContentWidth down to the message content avoiding lots of boilerplate
This commit is contained in:
@@ -296,6 +296,9 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
|
||||
qml/HoverLinkIndicator.qml
|
||||
qml/AvatarNotification.qml
|
||||
qml/ReasonDialog.qml
|
||||
SOURCES
|
||||
messageattached.cpp
|
||||
messageattached.h
|
||||
DEPENDENCIES
|
||||
QtCore
|
||||
QtQuick
|
||||
|
||||
@@ -349,7 +349,7 @@ QQC2.Control {
|
||||
replyEventId: _private.chatBarCache.replyId
|
||||
replyAuthor: _private.chatBarCache.relationAuthor
|
||||
replyContentModel: _private.chatBarCache.relationEventContentModel
|
||||
maxContentWidth: paneLoader.item.width
|
||||
Message.maxContentWidth: paneLoader.item.width
|
||||
}
|
||||
QQC2.Button {
|
||||
id: cancelButton
|
||||
|
||||
126
src/messageattached.cpp
Normal file
126
src/messageattached.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
// SPDX-FileCopyrightText: 2025 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include "messageattached.h"
|
||||
|
||||
MessageAttached::MessageAttached(QObject *parent)
|
||||
: QQuickAttachedPropertyPropagator(parent)
|
||||
{
|
||||
if (parent == nullptr) {
|
||||
qWarning() << "Message must be attached to an Item" << parent;
|
||||
return;
|
||||
}
|
||||
initialize();
|
||||
}
|
||||
|
||||
MessageAttached *MessageAttached::qmlAttachedProperties(QObject *object)
|
||||
{
|
||||
return new MessageAttached(object);
|
||||
}
|
||||
|
||||
NeoChatRoom *MessageAttached::room() const
|
||||
{
|
||||
return m_room;
|
||||
}
|
||||
|
||||
void MessageAttached::setRoom(NeoChatRoom *room)
|
||||
{
|
||||
m_explicitRoom = true;
|
||||
if (m_room == room) {
|
||||
return;
|
||||
}
|
||||
m_room = room;
|
||||
propagateMessage(this);
|
||||
Q_EMIT roomChanged();
|
||||
}
|
||||
|
||||
QQuickItem *MessageAttached::timeline() const
|
||||
{
|
||||
return m_timeline;
|
||||
}
|
||||
|
||||
void MessageAttached::setTimeline(QQuickItem *timeline)
|
||||
{
|
||||
m_explicitTimeline = true;
|
||||
if (m_timeline == timeline) {
|
||||
return;
|
||||
}
|
||||
m_timeline = timeline;
|
||||
propagateMessage(this);
|
||||
Q_EMIT timelineChanged();
|
||||
}
|
||||
|
||||
int MessageAttached::index() const
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
void MessageAttached::setIndex(int index)
|
||||
{
|
||||
m_explicitIndex = true;
|
||||
if (m_index == index) {
|
||||
return;
|
||||
}
|
||||
m_index = index;
|
||||
propagateMessage(this);
|
||||
Q_EMIT indexChanged();
|
||||
}
|
||||
|
||||
qreal MessageAttached::maxContentWidth() const
|
||||
{
|
||||
return m_maxContentWidth;
|
||||
}
|
||||
|
||||
void MessageAttached::setMaxContentWidth(qreal maxContentWidth)
|
||||
{
|
||||
m_explicitMaxContentWidth = true;
|
||||
if (m_maxContentWidth == maxContentWidth) {
|
||||
return;
|
||||
}
|
||||
m_maxContentWidth = maxContentWidth;
|
||||
propagateMessage(this);
|
||||
Q_EMIT maxContentWidthChanged();
|
||||
}
|
||||
|
||||
void MessageAttached::propagateMessage(MessageAttached *message)
|
||||
{
|
||||
if (m_explicitRoom || m_room != message->room()) {
|
||||
m_room = message->room();
|
||||
Q_EMIT roomChanged();
|
||||
}
|
||||
|
||||
if (m_explicitTimeline || m_timeline != message->timeline()) {
|
||||
m_timeline = message->timeline();
|
||||
Q_EMIT timelineChanged();
|
||||
}
|
||||
|
||||
if (m_explicitIndex || m_index != message->index()) {
|
||||
m_index = message->index();
|
||||
Q_EMIT indexChanged();
|
||||
}
|
||||
|
||||
if (m_explicitMaxContentWidth || m_maxContentWidth != message->maxContentWidth()) {
|
||||
m_maxContentWidth = message->maxContentWidth();
|
||||
Q_EMIT maxContentWidthChanged();
|
||||
}
|
||||
|
||||
const auto styles = attachedChildren();
|
||||
for (auto *child : attachedChildren()) {
|
||||
MessageAttached *message = qobject_cast<MessageAttached *>(child);
|
||||
if (message != nullptr) {
|
||||
message->propagateMessage(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageAttached::attachedParentChange(QQuickAttachedPropertyPropagator *newParent, QQuickAttachedPropertyPropagator *oldParent)
|
||||
{
|
||||
Q_UNUSED(oldParent);
|
||||
|
||||
MessageAttached *attachedParent = qobject_cast<MessageAttached *>(newParent);
|
||||
if (attachedParent) {
|
||||
propagateMessage(attachedParent);
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_messageattached.cpp"
|
||||
78
src/messageattached.h
Normal file
78
src/messageattached.h
Normal file
@@ -0,0 +1,78 @@
|
||||
// SPDX-FileCopyrightText: 2025 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QQmlEngine>
|
||||
#include <QQuickAttachedPropertyPropagator>
|
||||
#include <QQuickItem>
|
||||
|
||||
#include "neochatroom.h"
|
||||
|
||||
class MessageAttached : public QQuickAttachedPropertyPropagator
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(Message)
|
||||
QML_ATTACHED(MessageAttached)
|
||||
QML_UNCREATABLE("")
|
||||
|
||||
/**
|
||||
* @brief The room that the message comes from.
|
||||
*/
|
||||
Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged FINAL)
|
||||
|
||||
/**
|
||||
* @brief The timeline for the current message.
|
||||
*/
|
||||
Q_PROPERTY(QQuickItem *timeline READ timeline WRITE setTimeline NOTIFY timelineChanged FINAL)
|
||||
|
||||
/**
|
||||
* @brief The index of the message in the timeline
|
||||
*/
|
||||
Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged FINAL)
|
||||
|
||||
/**
|
||||
* @brief The width available to the message content.
|
||||
*/
|
||||
Q_PROPERTY(qreal maxContentWidth READ maxContentWidth WRITE setMaxContentWidth NOTIFY maxContentWidthChanged FINAL)
|
||||
|
||||
public:
|
||||
explicit MessageAttached(QObject *parent = nullptr);
|
||||
|
||||
static MessageAttached *qmlAttachedProperties(QObject *object);
|
||||
|
||||
NeoChatRoom *room() const;
|
||||
void setRoom(NeoChatRoom *room);
|
||||
|
||||
QQuickItem *timeline() const;
|
||||
void setTimeline(QQuickItem *timeline);
|
||||
|
||||
int index() const;
|
||||
void setIndex(int index);
|
||||
|
||||
qreal maxContentWidth() const;
|
||||
void setMaxContentWidth(qreal maxContentWidth);
|
||||
|
||||
Q_SIGNALS:
|
||||
void roomChanged();
|
||||
void timelineChanged();
|
||||
void indexChanged();
|
||||
void maxContentWidthChanged();
|
||||
|
||||
protected:
|
||||
void propagateMessage(MessageAttached *message);
|
||||
void attachedParentChange(QQuickAttachedPropertyPropagator *newParent, QQuickAttachedPropertyPropagator *oldParent) override;
|
||||
|
||||
private:
|
||||
QPointer<NeoChatRoom> m_room;
|
||||
bool m_explicitRoom = false;
|
||||
|
||||
QPointer<QQuickItem> m_timeline;
|
||||
bool m_explicitTimeline = false;
|
||||
|
||||
int m_index;
|
||||
bool m_explicitIndex = false;
|
||||
|
||||
qreal m_maxContentWidth = -1;
|
||||
bool m_explicitMaxContentWidth = false;
|
||||
};
|
||||
@@ -18,11 +18,6 @@ import org.kde.neochat
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The matrix ID of the message event.
|
||||
*/
|
||||
@@ -56,11 +51,6 @@ ColumnLayout {
|
||||
audio.play();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
MediaPlayer {
|
||||
id: audio
|
||||
onErrorOccurred: (error, errorString) => console.warn("Audio playback error:" + error + errorString)
|
||||
@@ -75,7 +65,7 @@ ColumnLayout {
|
||||
PropertyChanges {
|
||||
target: playButton
|
||||
icon.name: "media-playback-start"
|
||||
onClicked: root.room.downloadFile(root.eventId)
|
||||
onClicked: Message.room.downloadFile(root.eventId)
|
||||
}
|
||||
},
|
||||
State {
|
||||
@@ -89,7 +79,7 @@ ColumnLayout {
|
||||
target: playButton
|
||||
icon.name: "media-playback-stop"
|
||||
onClicked: {
|
||||
root.room.cancelFileTransfer(root.eventId);
|
||||
Message.room.cancelFileTransfer(root.eventId);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -159,7 +149,7 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
QQC2.Label {
|
||||
visible: root.maxContentWidth > Kirigami.Units.gridUnit * 12
|
||||
visible: root.Message.maxContentWidth > Kirigami.Units.gridUnit * 12
|
||||
|
||||
text: Format.formatDuration(audio.position) + "/" + Format.formatDuration(audio.duration)
|
||||
}
|
||||
@@ -167,7 +157,7 @@ ColumnLayout {
|
||||
QQC2.Label {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||
visible: audio.hasAudio && root.maxContentWidth < Kirigami.Units.gridUnit * 12
|
||||
visible: audio.hasAudio && root.Message.maxContentWidth < Kirigami.Units.gridUnit * 12
|
||||
|
||||
text: Format.formatDuration(audio.position) + "/" + Format.formatDuration(audio.duration)
|
||||
}
|
||||
|
||||
@@ -31,13 +31,8 @@ RowLayout {
|
||||
*/
|
||||
required property string timeString
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
implicitHeight: Math.max(nameButton.implicitHeight, timeLabel.implicitHeight)
|
||||
|
||||
|
||||
@@ -15,31 +15,6 @@ import org.kde.neochat
|
||||
DelegateChooser {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The index of the delegate in the model.
|
||||
*/
|
||||
required property var index
|
||||
|
||||
/**
|
||||
* @brief The timeline ListView this component is being used in.
|
||||
*/
|
||||
required property ListView timeline
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
/**
|
||||
* @brief The reply has been clicked.
|
||||
*/
|
||||
signal replyClicked(string eventID)
|
||||
|
||||
/**
|
||||
* @brief The user selected text has changed.
|
||||
*/
|
||||
@@ -66,15 +41,12 @@ DelegateChooser {
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Author
|
||||
delegate: AuthorComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: AuthorComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Text
|
||||
delegate: TextComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
onSelectedTextChanged: root.selectedTextChanged(selectedText)
|
||||
onHoveredLinkChanged: root.hoveredLinkChanged(hoveredLink)
|
||||
onShowMessageMenu: root.showMessageMenu()
|
||||
@@ -83,28 +55,17 @@ DelegateChooser {
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Image
|
||||
delegate: ImageComponent {
|
||||
room: root.room
|
||||
index: root.index
|
||||
timeline: root.timeline
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: ImageComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Video
|
||||
delegate: VideoComponent {
|
||||
room: root.room
|
||||
index: root.index
|
||||
timeline: root.timeline
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: VideoComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Code
|
||||
delegate: CodeComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
onSelectedTextChanged: selectedText => {
|
||||
root.selectedTextChanged(selectedText);
|
||||
}
|
||||
@@ -115,7 +76,6 @@ DelegateChooser {
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Quote
|
||||
delegate: QuoteComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
onSelectedTextChanged: selectedText => {
|
||||
root.selectedTextChanged(selectedText);
|
||||
}
|
||||
@@ -125,86 +85,57 @@ DelegateChooser {
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Audio
|
||||
delegate: AudioComponent {
|
||||
room: root.room
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: AudioComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.File
|
||||
delegate: FileComponent {
|
||||
room: root.room
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: FileComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Itinerary
|
||||
delegate: ItineraryComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: ItineraryComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Pdf
|
||||
delegate: PdfPreviewComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: PdfPreviewComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Poll
|
||||
delegate: PollComponent {
|
||||
room: root.room
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: PollComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Location
|
||||
delegate: LocationComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: LocationComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.LiveLocation
|
||||
delegate: LiveLocationComponent {
|
||||
room: root.room
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: LiveLocationComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Encrypted
|
||||
delegate: EncryptedComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: EncryptedComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Reply
|
||||
delegate: ReplyComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
onReplyClicked: eventId => {
|
||||
root.replyClicked(eventId);
|
||||
}
|
||||
}
|
||||
delegate: ReplyComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Reaction
|
||||
delegate: ReactionComponent {
|
||||
room: root.room
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: ReactionComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.LinkPreview
|
||||
delegate: LinkPreviewComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
onRemove: index => root.removeLinkPreview(index)
|
||||
}
|
||||
}
|
||||
@@ -213,31 +144,23 @@ DelegateChooser {
|
||||
roleValue: MessageComponentType.LinkPreviewLoad
|
||||
delegate: LinkPreviewLoadComponent {
|
||||
type: LinkPreviewLoadComponent.LinkPreview
|
||||
maxContentWidth: root.maxContentWidth
|
||||
onRemove: index => root.removeLinkPreview(index)
|
||||
}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.ChatBar
|
||||
delegate: ChatBarComponent {
|
||||
room: root.room
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: ChatBarComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.ReplyButton
|
||||
delegate: ReplyButtonComponent {
|
||||
room: root.room
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: ReplyButtonComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.FetchButton
|
||||
delegate: FetchButtonComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
onFetchMoreEvents: root.fetchMoreEvents()
|
||||
}
|
||||
}
|
||||
@@ -252,16 +175,14 @@ DelegateChooser {
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Loading
|
||||
delegate: LoadComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: LoadComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Separator
|
||||
delegate: Kirigami.Separator {
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,16 +22,6 @@ import org.kde.neochat
|
||||
QQC2.Control {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The index of the delegate in the model.
|
||||
*/
|
||||
required property var index
|
||||
|
||||
/**
|
||||
* @brief The message author.
|
||||
*
|
||||
@@ -66,23 +56,8 @@ QQC2.Control {
|
||||
*/
|
||||
property alias showBackground: bubbleBackground.visible
|
||||
|
||||
/**
|
||||
* @brief The timeline ListView this component is being used in.
|
||||
*/
|
||||
required property ListView timeline
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
required property bool isPending
|
||||
|
||||
/**
|
||||
* @brief The reply has been clicked.
|
||||
*/
|
||||
signal replyClicked(string eventID)
|
||||
|
||||
/**
|
||||
* @brief The user selected text has changed.
|
||||
*/
|
||||
@@ -108,6 +83,7 @@ QQC2.Control {
|
||||
ColumnLayout {
|
||||
id: contentColumn
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Repeater {
|
||||
id: contentRepeater
|
||||
model: MessageContentFilterModel {
|
||||
@@ -115,14 +91,6 @@ QQC2.Control {
|
||||
sourceModel: root.contentModel
|
||||
}
|
||||
delegate: MessageComponentChooser {
|
||||
room: root.room
|
||||
index: root.index
|
||||
timeline: root.timeline
|
||||
maxContentWidth: root.maxContentWidth
|
||||
|
||||
onReplyClicked: eventId => {
|
||||
root.replyClicked(eventId);
|
||||
}
|
||||
onSelectedTextChanged: selectedText => {
|
||||
root.selectedTextChanged(selectedText);
|
||||
}
|
||||
|
||||
@@ -16,25 +16,15 @@ import org.kde.neochat.chatbar
|
||||
QQC2.TextArea {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The ChatBarCache to use.
|
||||
*/
|
||||
required property ChatBarCache chatBarCache
|
||||
onChatBarCacheChanged: documentHandler.chatBarCache = chatBarCache
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: textMetrics.advanceWidth + rightPadding + Kirigami.Units.smallSpacing + Kirigami.Units.gridUnit
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
Layout.minimumHeight: chatButtons.height + topPadding + bottomPadding
|
||||
|
||||
Component.onCompleted: _private.updateText()
|
||||
@@ -124,7 +114,7 @@ QQC2.TextArea {
|
||||
height: implicitHeight
|
||||
y: -height - 5
|
||||
z: 10
|
||||
connection: root.room.connection
|
||||
connection: root.Message.room.connection
|
||||
chatDocumentHandler: documentHandler
|
||||
Behavior on height {
|
||||
NumberAnimation {
|
||||
@@ -144,7 +134,7 @@ QQC2.TextArea {
|
||||
cursorPosition: root.cursorPosition
|
||||
selectionStart: root.selectionStart
|
||||
selectionEnd: root.selectionEnd
|
||||
room: root.room // We don't care about saving for edits so this is OK.
|
||||
room: root.Message.room // We don't care about saving for edits so this is OK.
|
||||
mentionColor: Kirigami.Theme.linkColor
|
||||
errorColor: Kirigami.Theme.negativeTextColor
|
||||
}
|
||||
|
||||
@@ -37,11 +37,6 @@ QQC2.Control {
|
||||
*/
|
||||
required property var componentAttributes
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
/**
|
||||
* @brief The user selected text has changed.
|
||||
*/
|
||||
@@ -54,7 +49,7 @@ QQC2.Control {
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
Layout.maximumHeight: Kirigami.Units.gridUnit * 20
|
||||
|
||||
topPadding: 0
|
||||
@@ -64,7 +59,7 @@ QQC2.Control {
|
||||
|
||||
contentItem: QQC2.ScrollView {
|
||||
id: codeScrollView
|
||||
contentWidth: root.maxContentWidth
|
||||
contentWidth: root.Message.maxContentWidth
|
||||
|
||||
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
|
||||
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
|
||||
|
||||
@@ -6,17 +6,14 @@ import QtQuick.Layouts
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.neochat
|
||||
|
||||
/**
|
||||
* @brief A component for an encrypted message that can't be decrypted.
|
||||
*/
|
||||
TextEdit {
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
text: i18n("This message is encrypted and the sender has not shared the key with this device.")
|
||||
color: Kirigami.Theme.disabledTextColor
|
||||
|
||||
@@ -17,18 +17,13 @@ import org.kde.neochat.chatbar
|
||||
Delegates.RoundedItemDelegate {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
/**
|
||||
* @brief Request more events in the thread be loaded.
|
||||
*/
|
||||
signal fetchMoreEvents()
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
leftInset: 0
|
||||
rightInset: 0
|
||||
|
||||
@@ -20,11 +20,6 @@ import org.kde.neochat
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The matrix ID of the message event.
|
||||
*/
|
||||
@@ -65,14 +60,9 @@ ColumnLayout {
|
||||
*/
|
||||
property bool autoOpenFile: false
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
function saveFileAs() {
|
||||
const dialog = fileDialog.createObject(QQC2.Overlay.overlay);
|
||||
dialog.selectedFile = root.room.fileNameToDownload(root.eventId);
|
||||
dialog.selectedFile = Message.room.fileNameToDownload(root.eventId);
|
||||
dialog.open();
|
||||
}
|
||||
|
||||
@@ -81,7 +71,7 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
|
||||
RowLayout {
|
||||
@@ -138,7 +128,7 @@ ColumnLayout {
|
||||
target: downloadButton
|
||||
icon.name: "media-playback-stop"
|
||||
QQC2.ToolTip.text: i18nc("tooltip for a button on a message; stops downloading the message's file", "Stop Download")
|
||||
onClicked: root.room.cancelFileTransfer(root.eventId)
|
||||
onClicked: Message.room.cancelFileTransfer(root.eventId)
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -171,7 +161,7 @@ ColumnLayout {
|
||||
icon.name: "document-open"
|
||||
onClicked: {
|
||||
autoOpenFile = true;
|
||||
root.room.downloadTempFile(root.eventId);
|
||||
root.Message.room.downloadTempFile(root.eventId);
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: i18nc("tooltip for a button on a message; offers ability to open its downloaded file with an appropriate application", "Open File")
|
||||
@@ -201,7 +191,7 @@ ColumnLayout {
|
||||
if (autoOpenFile) {
|
||||
UrlHelper.copyTo(root.fileTransferInfo.localPath, selectedFile);
|
||||
} else {
|
||||
root.room.download(root.eventId, selectedFile);
|
||||
root.Message.room.download(root.eventId, selectedFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,16 +16,6 @@ import org.kde.neochat
|
||||
Item {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The index of the delegate in the model.
|
||||
*/
|
||||
required property var index
|
||||
|
||||
/**
|
||||
* @brief The matrix ID of the message event.
|
||||
*/
|
||||
@@ -56,16 +46,6 @@ Item {
|
||||
*/
|
||||
required property var fileTransferInfo
|
||||
|
||||
/**
|
||||
* @brief The timeline ListView this component is being used in.
|
||||
*/
|
||||
required property ListView timeline
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
implicitWidth: mediaSizeHelper.currentSize.width
|
||||
implicitHeight: mediaSizeHelper.currentSize.height
|
||||
|
||||
@@ -153,13 +133,13 @@ Item {
|
||||
if (root.mediaInfo.animated) {
|
||||
_private.imageItem.paused = true;
|
||||
}
|
||||
root.timeline.interactive = false;
|
||||
root.Message.timeline.interactive = false;
|
||||
if (!root.mediaInfo.isSticker) {
|
||||
// We need to make sure the index is that of the MediaMessageFilterModel.
|
||||
if (root.timeline.model instanceof MessageFilterModel) {
|
||||
RoomManager.maximizeMedia(RoomManager.mediaMessageFilterModel.getRowForSourceItem(root.index));
|
||||
if (root.Message.timeline.model instanceof MessageFilterModel) {
|
||||
RoomManager.maximizeMedia(RoomManager.mediaMessageFilterModel.getRowForSourceItem(root.Message.index));
|
||||
} else {
|
||||
RoomManager.maximizeMedia(root.index);
|
||||
RoomManager.maximizeMedia(root.Message.index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,7 +150,7 @@ Item {
|
||||
openSavedFile();
|
||||
} else {
|
||||
openOnFinished = true;
|
||||
root.room.downloadFile(root.eventId, StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/" + root.eventId.replace(":", "_").replace("/", "_").replace("+", "_") + root.room.fileNameToDownload(root.eventId));
|
||||
Message.room.downloadFile(root.eventId, StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/" + root.eventId.replace(":", "_").replace("/", "_").replace("+", "_") + Message.room.fileNameToDownload(root.eventId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +163,7 @@ Item {
|
||||
|
||||
MediaSizeHelper {
|
||||
id: mediaSizeHelper
|
||||
contentMaxWidth: root.maxContentWidth
|
||||
contentMaxWidth: root.Message.maxContentWidth
|
||||
mediaWidth: root?.mediaInfo.isSticker ? 256 : (root?.mediaInfo.width ?? 0)
|
||||
mediaHeight: root?.mediaInfo.isSticker ? 256 : (root?.mediaInfo.height ?? 0)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import Qt.labs.qmlmodels
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.neochat
|
||||
|
||||
/**
|
||||
* @brief A component to show a preview of a file that can integrate with KDE itinerary.
|
||||
*/
|
||||
@@ -20,13 +22,8 @@ ColumnLayout {
|
||||
*/
|
||||
required property var itineraryModel
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
|
||||
Repeater {
|
||||
|
||||
@@ -43,18 +43,13 @@ QQC2.Control {
|
||||
|
||||
property bool truncated: linkPreviewDescription.truncated || !linkPreviewDescription.visible
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
/**
|
||||
* @brief Request for this delegate to be removed.
|
||||
*/
|
||||
signal remove(int index)
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
Layout.minimumHeight: root.defaultHeight
|
||||
|
||||
leftPadding: 0
|
||||
|
||||
@@ -7,6 +7,8 @@ import QtQuick.Layouts
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.neochat
|
||||
|
||||
/**
|
||||
* @brief A component to show a link preview loading from a message.
|
||||
*/
|
||||
@@ -28,11 +30,6 @@ QQC2.Control {
|
||||
*/
|
||||
property var defaultHeight: Kirigami.Units.gridUnit * 3 + Kirigami.Units.smallSpacing * 2
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
/**
|
||||
* @brief Request for this delegate to be removed.
|
||||
*/
|
||||
@@ -44,7 +41,7 @@ QQC2.Control {
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
contentItem : RowLayout {
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
@@ -17,11 +17,6 @@ import org.kde.neochat
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The matrix ID of the message event.
|
||||
*/
|
||||
@@ -32,24 +27,19 @@ ColumnLayout {
|
||||
*/
|
||||
required property string display
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
LiveLocationsModel {
|
||||
id: liveLocationModel
|
||||
eventId: root.eventId
|
||||
room: root.room
|
||||
room: Message.room
|
||||
}
|
||||
MapView {
|
||||
id: mapView
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: root.maxContentWidth
|
||||
Layout.preferredHeight: root.maxContentWidth / 16 * 9
|
||||
Layout.preferredWidth: root.Message.maxContentWidth
|
||||
Layout.preferredHeight: root.Message.maxContentWidth / 16 * 9
|
||||
|
||||
map.center: QtPositioning.coordinate(liveLocationModel.boundingBox.y, liveLocationModel.boundingBox.x)
|
||||
map.zoomLevel: 15
|
||||
|
||||
@@ -7,6 +7,8 @@ import QtQuick.Layouts
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.neochat
|
||||
|
||||
/**
|
||||
* @brief A component to show that part of a message is loading.
|
||||
*/
|
||||
@@ -15,13 +17,8 @@ RowLayout {
|
||||
|
||||
required property string display
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
QQC2.BusyIndicator {}
|
||||
|
||||
@@ -49,19 +49,14 @@ ColumnLayout {
|
||||
*/
|
||||
required property string asset
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
MapView {
|
||||
id: mapView
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: root.maxContentWidth
|
||||
Layout.preferredHeight: root.maxContentWidth / 16 * 9
|
||||
Layout.preferredWidth: root.Message.maxContentWidth
|
||||
Layout.preferredHeight: root.Message.maxContentWidth / 16 * 9
|
||||
|
||||
map.center: QtPositioning.coordinate(root.latitude, root.longitude)
|
||||
map.zoomLevel: 15
|
||||
|
||||
@@ -14,11 +14,6 @@ BaseMessageComponentChooser {
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.ThreadBody
|
||||
delegate: ThreadBodyComponent {
|
||||
room: root.room
|
||||
index: root.index
|
||||
timeline: root.timeline
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: ThreadBodyComponent {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,12 +143,6 @@ TimelineDelegate {
|
||||
*/
|
||||
signal openExternally
|
||||
|
||||
/**
|
||||
* @brief The reply has been clicked.
|
||||
*/
|
||||
signal replyClicked(string eventID)
|
||||
onReplyClicked: eventID => ListView.view.goToEvent(eventID)
|
||||
|
||||
/**
|
||||
* @brief The main delegate content item to show in the bubble.
|
||||
*/
|
||||
@@ -198,6 +192,11 @@ TimelineDelegate {
|
||||
*/
|
||||
property real contentMaxWidth: (root.isThreaded ? bubbleSizeHelper.parentWidth : bubbleSizeHelper.currentWidth) - bubble.leftPadding - bubble.rightPadding
|
||||
|
||||
Message.room: root.room
|
||||
Message.timeline: root.ListView.view
|
||||
Message.index: root.index
|
||||
Message.maxContentWidth: contentMaxWidth
|
||||
|
||||
width: parent?.width
|
||||
rightPadding: NeoChatConfig.compactLayout && root.ListView.view.width >= Kirigami.Units.gridUnit * 20 ? Kirigami.Units.gridUnit * 2 + Kirigami.Units.largeSpacing : Kirigami.Units.largeSpacing
|
||||
|
||||
@@ -255,7 +254,6 @@ TimelineDelegate {
|
||||
anchors.left: avatar.right
|
||||
anchors.leftMargin: Kirigami.Units.largeSpacing
|
||||
anchors.rightMargin: rightPadding
|
||||
maxContentWidth: root.contentMaxWidth
|
||||
|
||||
topPadding: NeoChatConfig.compactLayout ? Kirigami.Units.smallSpacing / 2 : Kirigami.Units.largeSpacing
|
||||
bottomPadding: NeoChatConfig.compactLayout ? Kirigami.Units.mediumSpacing / 2 : Kirigami.Units.largeSpacing
|
||||
@@ -284,22 +282,16 @@ TimelineDelegate {
|
||||
}
|
||||
]
|
||||
|
||||
room: root.room
|
||||
index: root.index
|
||||
author: root.author
|
||||
showAuthor: root.showAuthor
|
||||
isThreaded: root.isThreaded
|
||||
|
||||
contentModel: root.contentModel
|
||||
timeline: root.ListView.view
|
||||
|
||||
showHighlight: root.showHighlight
|
||||
|
||||
isPending: root.isPending
|
||||
|
||||
onReplyClicked: eventId => {
|
||||
root.replyClicked(eventId);
|
||||
}
|
||||
onSelectedTextChanged: selectedText => {
|
||||
root.selectedText = selectedText;
|
||||
}
|
||||
|
||||
@@ -20,11 +20,6 @@ Rectangle {
|
||||
*/
|
||||
required property var componentAttributes
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.preferredWidth: mediaSizeHelper.currentSize.width
|
||||
Layout.preferredHeight: mediaSizeHelper.currentSize.height
|
||||
|
||||
@@ -36,7 +31,7 @@ Rectangle {
|
||||
|
||||
MediaSizeHelper {
|
||||
id: mediaSizeHelper
|
||||
contentMaxWidth: root.maxContentWidth
|
||||
contentMaxWidth: root.Message.maxContentWidth
|
||||
mediaWidth: root.componentAttributes.size.width
|
||||
mediaHeight: root.componentAttributes.size.height
|
||||
}
|
||||
|
||||
@@ -16,11 +16,6 @@ import org.kde.neochat
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The matrix ID of the message event.
|
||||
*/
|
||||
@@ -34,13 +29,8 @@ ColumnLayout {
|
||||
*/
|
||||
required property var pollHandler
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
spacing: 0
|
||||
|
||||
@@ -59,7 +49,7 @@ ColumnLayout {
|
||||
Layout.leftMargin: -Kirigami.Units.largeSpacing - Kirigami.Units.smallSpacing
|
||||
Layout.rightMargin: -Kirigami.Units.largeSpacing - Kirigami.Units.smallSpacing
|
||||
|
||||
checked: root.pollHandler.answers[root.room.localMember.id] ? root.pollHandler.answers[root.room.localMember.id].includes(modelData["id"]) : false
|
||||
checked: root.pollHandler.answers[root.Message.room.localMember.id] ? root.pollHandler.answers[root.Message.room.localMember.id].includes(modelData["id"]) : false
|
||||
onClicked: root.pollHandler.sendPollAnswer(root.eventId, modelData["id"])
|
||||
enabled: !root.pollHandler.hasEnded
|
||||
text: modelData["org.matrix.msc1767.text"]
|
||||
|
||||
@@ -7,6 +7,8 @@ import QtQuick.Layouts
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
import org.kde.neochat
|
||||
|
||||
QQC2.Control {
|
||||
id: root
|
||||
|
||||
@@ -15,11 +17,6 @@ QQC2.Control {
|
||||
*/
|
||||
required property string display
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
/**
|
||||
* @brief The user selected text has changed.
|
||||
*/
|
||||
@@ -32,7 +29,7 @@ QQC2.Control {
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
|
||||
@@ -13,11 +13,6 @@ import org.kde.neochat
|
||||
Flow {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The matrix ID of the message event.
|
||||
*/
|
||||
@@ -28,14 +23,9 @@ Flow {
|
||||
*/
|
||||
required property ReactionModel reactionModel
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
@@ -79,7 +69,9 @@ Flow {
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: root.room.toggleReaction(root.eventId, reactionDelegate.reaction)
|
||||
onClicked: {
|
||||
root.Message.room.toggleReaction(root.eventId, reactionDelegate.reaction)
|
||||
}
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
@@ -114,7 +106,7 @@ Flow {
|
||||
onClicked: {
|
||||
var dialog = emojiDialog.createObject(reactButton);
|
||||
dialog.chosen.connect(emoji => {
|
||||
root.room.toggleReaction(root.eventId, emoji);
|
||||
root.Message.room.toggleReaction(root.eventId, emoji);
|
||||
if (!Kirigami.Settings.isMobile) {
|
||||
root.focusChatBar();
|
||||
}
|
||||
@@ -133,7 +125,7 @@ Flow {
|
||||
id: emojiDialog
|
||||
|
||||
EmojiDialog {
|
||||
currentRoom: root.room
|
||||
currentRoom: root.Message.room
|
||||
showQuickReaction: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,23 +17,13 @@ import org.kde.neochat.chatbar
|
||||
Delegates.RoundedItemDelegate {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The thread root ID.
|
||||
*/
|
||||
required property string threadRoot
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
leftInset: 0
|
||||
rightInset: 0
|
||||
@@ -44,9 +34,9 @@ Delegates.RoundedItemDelegate {
|
||||
text: i18nc("@action:button", "Reply")
|
||||
|
||||
onClicked: {
|
||||
root.room.threadCache.replyId = "";
|
||||
root.room.threadCache.threadId = root.threadRoot;
|
||||
root.room.mainCache.clearRelations();
|
||||
root.room.editCache.clearRelations();
|
||||
Message.room.threadCache.replyId = "";
|
||||
Message.room.threadCache.threadId = root.threadRoot;
|
||||
Message.room.mainCache.clearRelations();
|
||||
Message.room.editCache.clearRelations();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,16 +43,6 @@ RowLayout {
|
||||
*/
|
||||
required property var replyContentModel
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
/**
|
||||
* @brief The reply has been clicked.
|
||||
*/
|
||||
signal replyClicked(string eventID)
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
@@ -69,13 +59,13 @@ RowLayout {
|
||||
id: contentColumn
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Message.maxContentWidth: _private.availableContentWidth
|
||||
|
||||
Repeater {
|
||||
id: contentRepeater
|
||||
model: root.replyContentModel
|
||||
delegate: ReplyMessageComponentChooser {
|
||||
maxContentWidth: _private.availableContentWidth
|
||||
|
||||
onReplyClicked: root.replyClicked(root.replyEventId)
|
||||
onReplyClicked: root.Message.timeline.goToEvent(root.replyEventId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,11 +74,11 @@ RowLayout {
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onTapped: root.replyClicked(root.replyEventId)
|
||||
onTapped: root.Message.timeline.goToEvent(root.replyEventId)
|
||||
}
|
||||
QtObject {
|
||||
id: _private
|
||||
// The space available for the component after taking away the border
|
||||
readonly property real availableContentWidth: root.maxContentWidth - verticalBorder.implicitWidth - root.spacing
|
||||
readonly property real availableContentWidth: root.Message.maxContentWidth - verticalBorder.implicitWidth - root.spacing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,6 @@ import org.kde.neochat
|
||||
DelegateChooser {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
/**
|
||||
* @brief The reply has been clicked.
|
||||
*/
|
||||
@@ -29,16 +24,12 @@ DelegateChooser {
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Author
|
||||
delegate: ReplyAuthorComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: ReplyAuthorComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Text
|
||||
delegate: TextComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
@@ -61,7 +52,7 @@ DelegateChooser {
|
||||
|
||||
MediaSizeHelper {
|
||||
id: mediaSizeHelper
|
||||
contentMaxWidth: root.maxContentWidth
|
||||
contentMaxWidth: Message.maxContentWidth
|
||||
contentMaxHeight: Kirigami.Units.gridUnit * 5
|
||||
mediaWidth: image.mediaInfo.width ?? 0
|
||||
mediaHeight: image.mediaInfo.height ?? 0
|
||||
@@ -85,7 +76,6 @@ DelegateChooser {
|
||||
roleValue: MessageComponentType.Code
|
||||
delegate: CodeComponent {
|
||||
Layout.maximumHeight: Kirigami.Units.gridUnit * 5
|
||||
maxContentWidth: root.maxContentWidth
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
@@ -99,8 +89,6 @@ DelegateChooser {
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Quote
|
||||
delegate: QuoteComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
@@ -137,10 +125,7 @@ DelegateChooser {
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Poll
|
||||
delegate: PollComponent {
|
||||
room: root.room
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: PollComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
@@ -161,16 +146,12 @@ DelegateChooser {
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Encrypted
|
||||
delegate: EncryptedComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: EncryptedComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
roleValue: MessageComponentType.Loading
|
||||
delegate: LoadComponent {
|
||||
maxContentWidth: root.maxContentWidth
|
||||
}
|
||||
delegate: LoadComponent {}
|
||||
}
|
||||
|
||||
DelegateChoice {
|
||||
|
||||
@@ -35,11 +35,6 @@ TextEdit {
|
||||
*/
|
||||
property bool spoilerRevealed: !hasSpoiler.test(display)
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
/**
|
||||
* @brief Request a context menu be show for the message.
|
||||
*/
|
||||
@@ -47,7 +42,7 @@ TextEdit {
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
|
||||
ListView.onReused: Qt.binding(() => !hasSpoiler.test(display))
|
||||
|
||||
|
||||
@@ -16,36 +16,11 @@ import org.kde.neochat
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The index of the delegate in the model.
|
||||
*/
|
||||
required property var index
|
||||
|
||||
/**
|
||||
* @brief The Matrix ID of the root message in the thread, if any.
|
||||
*/
|
||||
required property string threadRoot
|
||||
|
||||
/**
|
||||
* @brief The timeline ListView this component is being used in.
|
||||
*/
|
||||
required property ListView timeline
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
/**
|
||||
* @brief The reply has been clicked.
|
||||
*/
|
||||
signal replyClicked(string eventID)
|
||||
|
||||
/**
|
||||
* @brief The user selected text has changed.
|
||||
*/
|
||||
@@ -63,22 +38,14 @@ ColumnLayout {
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.maximumWidth: root.maxContentWidth
|
||||
Layout.maximumWidth: Message.maxContentWidth
|
||||
spacing: Kirigami.Units.smallSpacing
|
||||
|
||||
Repeater {
|
||||
id: threadRepeater
|
||||
model: root.room.modelForThread(root.threadRoot);
|
||||
model: root.Message.room.modelForThread(root.threadRoot);
|
||||
|
||||
delegate: BaseMessageComponentChooser {
|
||||
room: root.room
|
||||
index: root.index
|
||||
timeline: root.timeline
|
||||
maxContentWidth: root.maxContentWidth
|
||||
|
||||
onReplyClicked: eventId => {
|
||||
root.replyClicked(eventId);
|
||||
}
|
||||
onSelectedTextChanged: selectedText => {
|
||||
root.selectedTextChanged(selectedText);
|
||||
}
|
||||
|
||||
@@ -19,16 +19,6 @@ import org.kde.neochat
|
||||
Video {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* @brief The NeoChatRoom the delegate is being displayed in.
|
||||
*/
|
||||
required property NeoChatRoom room
|
||||
|
||||
/**
|
||||
* @brief The index of the delegate in the model.
|
||||
*/
|
||||
required property var index
|
||||
|
||||
/**
|
||||
* @brief The matrix ID of the message event.
|
||||
*/
|
||||
@@ -77,16 +67,6 @@ Video {
|
||||
*/
|
||||
property bool playOnFinished: false
|
||||
|
||||
/**
|
||||
* @brief The timeline ListView this component is being used in.
|
||||
*/
|
||||
required property ListView timeline
|
||||
|
||||
/**
|
||||
* @brief The maximum width that the bubble's content can be.
|
||||
*/
|
||||
property real maxContentWidth: -1
|
||||
|
||||
Layout.preferredWidth: mediaSizeHelper.currentSize.width
|
||||
Layout.preferredHeight: mediaSizeHelper.currentSize.height
|
||||
|
||||
@@ -382,13 +362,13 @@ Video {
|
||||
text: i18n("Maximize")
|
||||
icon.name: "view-fullscreen"
|
||||
onTriggered: {
|
||||
root.timeline.interactive = false;
|
||||
root.Message.timeline.interactive = false;
|
||||
root.pause();
|
||||
// We need to make sure the index is that of the MediaMessageFilterModel.
|
||||
if (root.timeline.model instanceof MessageFilterModel) {
|
||||
RoomManager.maximizeMedia(RoomManager.mediaMessageFilterModel.getRowForSourceItem(root.index));
|
||||
if (root.Message.timeline.model instanceof MessageFilterModel) {
|
||||
RoomManager.maximizeMedia(RoomManager.mediaMessageFilterModel.getRowForSourceItem(root.Message.index));
|
||||
} else {
|
||||
RoomManager.maximizeMedia(root.index);
|
||||
RoomManager.maximizeMedia(root.Message.index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -440,7 +420,7 @@ Video {
|
||||
|
||||
MediaSizeHelper {
|
||||
id: mediaSizeHelper
|
||||
contentMaxWidth: root.maxContentWidth
|
||||
contentMaxWidth: root.Message.maxContentWidth
|
||||
mediaWidth: root.mediaInfo.width
|
||||
mediaHeight: root.mediaInfo.height
|
||||
}
|
||||
@@ -450,7 +430,7 @@ Video {
|
||||
playSavedFile();
|
||||
} else {
|
||||
playOnFinished = true;
|
||||
root.room.downloadFile(root.eventId, Core.StandardPaths.writableLocation(Core.StandardPaths.CacheLocation) + "/" + root.eventId.replace(":", "_").replace("/", "_").replace("+", "_") + root.room.fileNameToDownload(root.eventId));
|
||||
Message.room.downloadFile(root.eventId, Core.StandardPaths.writableLocation(Core.StandardPaths.CacheLocation) + "/" + root.eventId.replace(":", "_").replace("/", "_").replace("+", "_") + Message.room.fileNameToDownload(root.eventId));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user