adds reactions
This commit is contained in:
@@ -49,6 +49,8 @@ HRowLayout {
|
||||
">"
|
||||
) + "</font></font></a>"
|
||||
|
||||
readonly property var reactions: model.reactions
|
||||
|
||||
readonly property bool pureMedia: ! contentText && linksRepeater.count
|
||||
|
||||
readonly property bool hoveredSelectable: contentHover.hovered
|
||||
@@ -298,6 +300,8 @@ HRowLayout {
|
||||
|
||||
linksRepeater.summedWidth +
|
||||
(pureMedia ? 0 : parent.leftPadding + parent.rightPadding),
|
||||
|
||||
reactionsRow.width
|
||||
)
|
||||
height: contentColumn.height
|
||||
radius: theme.chat.message.radius
|
||||
@@ -361,6 +365,94 @@ HRowLayout {
|
||||
Layout.preferredHeight: item ? item.height : -1
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: reactionsRow
|
||||
|
||||
spacing: 10
|
||||
bottomPadding: 7
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
Layout.alignment: onRight ? Qt.AlignRight : Qt.AlignLeft
|
||||
|
||||
Repeater {
|
||||
id: reactionsRepeater
|
||||
|
||||
model: {
|
||||
const reactions = Object.entries(
|
||||
JSON.parse(eventDelegate.currentModel.reactions));
|
||||
return reactions;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: reactionItem
|
||||
|
||||
required property var modelData
|
||||
readonly property var icon: modelData[0]
|
||||
readonly property var hint: modelData[1]["hint"]
|
||||
readonly property var users: modelData[1]["users"]
|
||||
|
||||
width: reactionContent.width
|
||||
height: theme.fontSize.normal + 10
|
||||
radius: width / 2
|
||||
color: theme.colors.strongBackground
|
||||
border.color: theme.colors.accentBackground
|
||||
border.width: 1
|
||||
|
||||
Row {
|
||||
id: reactionContent
|
||||
spacing: 5
|
||||
topPadding: 3
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
Text {
|
||||
id: reactionIcon
|
||||
color: theme.colors.brightText
|
||||
font.pixelSize: theme.fontSize.normal
|
||||
font.family: theme.fontFamily.sans
|
||||
text: parent.parent.icon
|
||||
}
|
||||
Text {
|
||||
id: reactionCounter
|
||||
color: theme.colors.brightText
|
||||
font.pixelSize: theme.fontSize.normal
|
||||
font.family: theme.fontFamily.sans
|
||||
text: parent.parent.users.length
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: reactionItemMouseArea
|
||||
anchors.fill: parent
|
||||
onEntered: { reactionTooltip.visible = true }
|
||||
onExited: { reactionTooltip.visible = false }
|
||||
hoverEnabled: true
|
||||
}
|
||||
|
||||
HToolTip {
|
||||
id: reactionTooltip
|
||||
visible: false
|
||||
|
||||
label.textFormat: HLabel.StyledText
|
||||
text: {
|
||||
const members =
|
||||
ModelStore.get(chat.userId, chat.roomId, "members")
|
||||
|
||||
const lines = [parent.hint]
|
||||
for (const userId of parent.users) {
|
||||
const member = members.find(userId)
|
||||
|
||||
const by = utils.coloredNameHtml(
|
||||
member ? member.display_name: userId, userId,
|
||||
)
|
||||
lines.push(qsTr("%1").arg(by))
|
||||
}
|
||||
return lines.join("<br>")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HSpacer {}
|
||||
|
@@ -72,20 +72,26 @@ HColumnLayout {
|
||||
eventList.toggleCheck(model.index)
|
||||
}
|
||||
|
||||
visible: !model.hidden
|
||||
width: eventList.width - eventList.leftMargin - eventList.rightMargin
|
||||
|
||||
// Needed because of eventList's MouseArea which steals the
|
||||
// HSelectableLabel's MouseArea hover events
|
||||
onCursorShapeChanged: eventList.cursorShape = cursorShape
|
||||
|
||||
Component.onCompleted: if (model.fetch_profile)
|
||||
fetchProfilesFutureId = py.callClientCoro(
|
||||
chat.userId,
|
||||
"get_event_profiles",
|
||||
[chat.roomId, model.id],
|
||||
// The if avoids segfault if eventDelegate is already destroyed
|
||||
() => { if (eventDelegate) fetchProfilesFutureId = "" }
|
||||
)
|
||||
Component.onCompleted: {
|
||||
if (model.fetch_profile)
|
||||
fetchProfilesFutureId = py.callClientCoro(
|
||||
chat.userId,
|
||||
"get_event_profiles",
|
||||
[chat.roomId, model.id],
|
||||
// The if avoids segfault if eventDelegate is already destroyed
|
||||
() => { if (eventDelegate) fetchProfilesFutureId = "" }
|
||||
)
|
||||
// Workaround for hiding messages of certain types
|
||||
if (!eventDelegate.visible)
|
||||
eventDelegate.height = 0
|
||||
}
|
||||
|
||||
Component.onDestruction:
|
||||
if (fetchProfilesFutureId) py.cancelCoro(fetchProfilesFutureId)
|
||||
|
@@ -266,10 +266,26 @@ Rectangle {
|
||||
highlightRangeMode = previous
|
||||
}
|
||||
|
||||
function focusPreviousVisibleMessage() {
|
||||
incrementCurrentIndex()
|
||||
let lastIndex = -1
|
||||
while ( currentIndex != lastIndex && model.get(currentIndex).hidden ) {
|
||||
lastIndex = currentIndex
|
||||
incrementCurrentIndex()
|
||||
}
|
||||
}
|
||||
|
||||
function focusPreviousMessage() {
|
||||
currentIndex === -1 && visibleEnd.y < contentHeight - height / 4 ?
|
||||
focusCenterMessage() :
|
||||
incrementCurrentIndex()
|
||||
focusPreviousVisibleMessage()
|
||||
}
|
||||
|
||||
function focusNextVisibleMessage() {
|
||||
decrementCurrentIndex()
|
||||
while ( currentIndex > -1 && model.get(currentIndex).hidden ) {
|
||||
decrementCurrentIndex()
|
||||
}
|
||||
}
|
||||
|
||||
function focusNextMessage() {
|
||||
@@ -279,7 +295,7 @@ Rectangle {
|
||||
eventList.currentIndex === 0 ?
|
||||
eventList.currentIndex = -1 :
|
||||
|
||||
decrementCurrentIndex()
|
||||
focusNextVisibleMessage()
|
||||
}
|
||||
|
||||
function copySelectedDelegates() {
|
||||
@@ -332,7 +348,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
function canCombine(item, itemAfter) {
|
||||
if (! item || ! itemAfter) return false
|
||||
if (! item || ! itemAfter || item.hidden) return false
|
||||
|
||||
return Boolean(
|
||||
! canTalkBreak(item, itemAfter) &&
|
||||
|
Reference in New Issue
Block a user