Depends on https://github.com/quotient-im/libQuotient/pull/695 Currently basic just to show a working implementation using RoomMember. Currently only the room event and search models are moved over. Will change everything else over once the dependent pr is complete.
190 lines
5.6 KiB
QML
190 lines
5.6 KiB
QML
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
|
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
|
|
import QtQuick
|
|
import QtQuick.Controls as QQC2
|
|
import QtQuick.Layouts
|
|
|
|
import org.kde.kirigami as Kirigami
|
|
|
|
import org.kde.neochat
|
|
|
|
/**
|
|
* @brief A chat bubble for displaying the content of message events.
|
|
*
|
|
* The content of the bubble is set via the content property which is then managed
|
|
* by the bubble to apply the correct sizing (including limiting the width if a
|
|
* maxContentWidth is set).
|
|
*
|
|
* The bubble also supports a header with the author and message timestamp and a
|
|
* reply.
|
|
*/
|
|
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.
|
|
*
|
|
* A Quotient::RoomMember object.
|
|
*
|
|
* @sa Quotient::RoomMember
|
|
*/
|
|
property var author
|
|
|
|
/**
|
|
* @brief Whether the author should be shown.
|
|
*/
|
|
required property bool showAuthor
|
|
|
|
/**
|
|
* @brief The timestamp of the message.
|
|
*/
|
|
property var time
|
|
|
|
/**
|
|
* @brief The timestamp of the message as a string.
|
|
*/
|
|
property string timeString
|
|
|
|
/**
|
|
* @brief Whether the message should be highlighted.
|
|
*/
|
|
property bool showHighlight: false
|
|
|
|
/**
|
|
* @brief The model to visualise the content of the message.
|
|
*/
|
|
required property MessageContentModel contentModel
|
|
|
|
/**
|
|
* @brief The ActionsHandler object to use.
|
|
*
|
|
* This is expected to have the correct room set otherwise messages will be sent
|
|
* to the wrong room.
|
|
*/
|
|
property ActionsHandler actionsHandler
|
|
|
|
/**
|
|
* @brief Whether the bubble background should be shown.
|
|
*/
|
|
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
|
|
|
|
/**
|
|
* @brief The reply has been clicked.
|
|
*/
|
|
signal replyClicked(string eventID)
|
|
|
|
/**
|
|
* @brief The user selected text has changed.
|
|
*/
|
|
signal selectedTextChanged(string selectedText)
|
|
|
|
/**
|
|
* @brief Request a context menu be show for the message.
|
|
*/
|
|
signal showMessageMenu
|
|
|
|
contentItem: ColumnLayout {
|
|
id: contentColumn
|
|
spacing: Kirigami.Units.smallSpacing
|
|
RowLayout {
|
|
id: headerRow
|
|
Layout.maximumWidth: root.maxContentWidth
|
|
implicitHeight: Math.max(nameButton.implicitHeight, timeLabel.implicitHeight)
|
|
visible: root.showAuthor
|
|
QQC2.AbstractButton {
|
|
id: nameButton
|
|
Layout.fillWidth: true
|
|
contentItem: QQC2.Label {
|
|
text: root.author.disambiguatedName
|
|
color: root.author.color
|
|
textFormat: Text.PlainText
|
|
font.weight: Font.Bold
|
|
elide: Text.ElideRight
|
|
}
|
|
Accessible.name: contentItem.text
|
|
onClicked: RoomManager.resolveResource(root.author.uri)
|
|
}
|
|
QQC2.Label {
|
|
id: timeLabel
|
|
text: root.timeString
|
|
horizontalAlignment: Text.AlignRight
|
|
color: Kirigami.Theme.disabledTextColor
|
|
QQC2.ToolTip.visible: timeHoverHandler.hovered
|
|
QQC2.ToolTip.text: root.time.toLocaleString(Qt.locale(), Locale.LongFormat)
|
|
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
|
|
|
HoverHandler {
|
|
id: timeHoverHandler
|
|
}
|
|
}
|
|
}
|
|
Repeater {
|
|
id: contentRepeater
|
|
model: root.contentModel
|
|
delegate: MessageComponentChooser {
|
|
room: root.room
|
|
index: root.index
|
|
time: root.time
|
|
actionsHandler: root.actionsHandler
|
|
timeline: root.timeline
|
|
maxContentWidth: root.maxContentWidth
|
|
|
|
onReplyClicked: eventId => {
|
|
root.replyClicked(eventId);
|
|
}
|
|
onSelectedTextChanged: selectedText => {
|
|
root.selectedTextChanged(selectedText);
|
|
}
|
|
onShowMessageMenu: root.showMessageMenu()
|
|
onRemoveLinkPreview: index => root.contentModel.closeLinkPreview(index)
|
|
}
|
|
}
|
|
}
|
|
|
|
background: Kirigami.ShadowedRectangle {
|
|
id: bubbleBackground
|
|
visible: root.showBackground
|
|
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
|
Kirigami.Theme.inherit: false
|
|
color: if (root.author.isLocalMember) {
|
|
return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.15);
|
|
} else if (root.showHighlight) {
|
|
return Kirigami.Theme.positiveBackgroundColor;
|
|
} else {
|
|
return Kirigami.Theme.backgroundColor;
|
|
}
|
|
radius: Kirigami.Units.cornerRadius
|
|
shadow {
|
|
size: Kirigami.Units.smallSpacing
|
|
color: root.showHighlight ? Qt.rgba(0.0, 0.0, 0.0, 0.10) : Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.10)
|
|
}
|
|
|
|
Behavior on color {
|
|
ColorAnimation {
|
|
duration: Kirigami.Units.shortDuration
|
|
}
|
|
}
|
|
}
|
|
}
|