Reaction Model

Create a reaction model that provides all the required data for `ReactionDelegate` so that none need to be calculated in QML.

This also cleans up the API for `ReactionDelegate`
This commit is contained in:
James Graham
2023-05-16 16:44:02 +00:00
parent 4d2e64cb80
commit a5a2c0b03e
8 changed files with 302 additions and 65 deletions

View File

@@ -4,67 +4,64 @@
import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami
Flow {
id: root
/**
* @brief The reaction model to get the reactions from.
*/
property alias model: reactionRepeater.model
/**
* @brief The given reaction has been clicked.
*
* Thrown when one of the reaction buttons in the flow is clicked.
*/
signal reactionClicked(string reaction)
spacing: Kirigami.Units.smallSpacing
Repeater {
model: reaction ?? null
id: reactionRepeater
model: root.model
delegate: QQC2.AbstractButton {
width: Math.max(implicitWidth, height)
width: Math.max(reactionTextMetrics.advanceWidth + Kirigami.Units.smallSpacing * 4, height)
contentItem: QQC2.Label {
id: reactionLabel
horizontalAlignment: Text.AlignHCenter
text: modelData.reaction + " " + modelData.count
verticalAlignment: Text.AlignVCenter
text: model.text
TextMetrics {
id: reactionTextMetrics
text: reactionLabel.text
}
}
padding: Kirigami.Units.smallSpacing
background: Kirigami.ShadowedRectangle {
color: checked ? Kirigami.Theme.positiveBackgroundColor : Kirigami.Theme.backgroundColor
color: model.hasLocalUser ? Kirigami.Theme.positiveBackgroundColor : Kirigami.Theme.backgroundColor
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.View
radius: height / 2
shadow.size: Kirigami.Units.smallSpacing
shadow.color: !model.isHighlighted ? 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)
shadow.color: !model.hasLocalUser ? 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)
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
border.width: 1
}
checkable: true
checked: modelData.hasLocalUser
onToggled: currentRoom.toggleReaction(eventId, modelData.reaction)
onClicked: reactionClicked(model.reaction)
hoverEnabled: true
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.text: {
var text = "";
for (var i = 0; i < modelData.authors.length && i < 3; i++) {
if (i !== 0) {
if (i < modelData.authors.length - 1) {
text += ", "
} else {
text += i18nc("Separate the usernames of users", " and ")
}
}
text += currentRoom.htmlSafeMemberName(modelData.authors[i].id)
}
if (modelData.authors.length > 3) {
text += i18ncp("%1 is the number of other users", " and %1 other", " and %1 others", modelData.authors.length - 3)
}
text = i18ncp("%2 is the users who reacted and %3 the emoji that was given", "%2 reacted with %3", "%2 reacted with %3", modelData.authors.length, text, modelData.reaction)
return text
}
QQC2.ToolTip.text: model.toolTip
}
}
}

View File

@@ -334,7 +334,10 @@ ColumnLayout {
Layout.leftMargin: showUserMessageOnRight ? 0 : bubble.x + bubble.anchors.leftMargin
Layout.rightMargin: showUserMessageOnRight ? Kirigami.Units.largeSpacing : 0
visible: delegateType !== MessageEventModel.State && delegateType !== MessageEventModel.Notice && reaction != undefined && reaction.length > 0
visible: showReactions
model: reaction
onReactionClicked: (reaction) => currentRoom.toggleReaction(eventId, reaction)
}
AvatarFlow {
Layout.alignment: Qt.AlignRight