mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Add reaction/redaction for in-line Reactions
This commit is contained in:
parent
1c521d1711
commit
5228861b88
8 changed files with 65 additions and 14 deletions
|
@ -1,7 +1,21 @@
|
|||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.2
|
||||
|
||||
// This class is for showing Reactions in the timeline row, not for
|
||||
// adding new reactions via the emoji picker
|
||||
Flow {
|
||||
id: reactionFlow
|
||||
// Signal for when a reaction is picked / unpicked
|
||||
signal picked(string room_id, string event_id, string key, string selfReactedEvent)
|
||||
|
||||
// highlight colors for selfReactedEvent background
|
||||
property real highlightHue: colors.highlight.hslHue
|
||||
property real highlightSat: colors.highlight.hslSaturation
|
||||
property real highlightLight: colors.highlight.hslLightness
|
||||
|
||||
property string eventId
|
||||
property string roomId
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: 4
|
||||
|
@ -11,7 +25,7 @@ Flow {
|
|||
Repeater {
|
||||
id: repeater
|
||||
|
||||
AbstractButton {
|
||||
delegate: AbstractButton {
|
||||
id: reaction
|
||||
hoverEnabled: true
|
||||
implicitWidth: contentItem.childrenRect.width + contentItem.leftPadding*2
|
||||
|
@ -20,6 +34,11 @@ Flow {
|
|||
ToolTip.visible: hovered
|
||||
ToolTip.text: model.users
|
||||
|
||||
onClicked: {
|
||||
console.debug("Picked " + model.key + "in response to " + reactionFlow.eventId + " in room " + reactionFlow.roomId + ". selfReactedEvent: " + model.selfReactedEvent)
|
||||
reactionFlow.picked(reactionFlow.roomId, reactionFlow.eventId, model.key, model.selfReactedEvent)
|
||||
}
|
||||
|
||||
|
||||
contentItem: Row {
|
||||
anchors.centerIn: parent
|
||||
|
@ -48,7 +67,7 @@ Flow {
|
|||
id: divider
|
||||
height: reactionCounter.implicitHeight * 1.4
|
||||
width: 1
|
||||
color: reaction.hovered ? colors.highlight : colors.text
|
||||
color: (reaction.hovered || model.selfReactedEvent !== '') ? colors.highlight : colors.text
|
||||
}
|
||||
|
||||
Text {
|
||||
|
@ -62,10 +81,11 @@ Flow {
|
|||
|
||||
background: Rectangle {
|
||||
anchors.centerIn: parent
|
||||
|
||||
implicitWidth: reaction.implicitWidth
|
||||
implicitHeight: reaction.implicitHeight
|
||||
border.color: (reaction.hovered || model.selfReacted )? colors.highlight : colors.text
|
||||
color: colors.base
|
||||
border.color: (reaction.hovered || model.selfReactedEvent !== '') ? colors.highlight : colors.text
|
||||
color: model.selfReactedEvent !== '' ? Qt.hsla(highlightHue, highlightSat, highlightLight, 0.20) : colors.base
|
||||
border.width: 1
|
||||
radius: reaction.height / 2.0
|
||||
}
|
||||
|
|
|
@ -59,7 +59,13 @@ MouseArea {
|
|||
}
|
||||
|
||||
Reactions {
|
||||
id: reactionRow
|
||||
reactions: model.reactions
|
||||
roomId: model.roomId
|
||||
eventId: model.id
|
||||
Component.onCompleted: {
|
||||
reactionRow.picked.connect(timelineManager.reactToMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,9 @@ Page {
|
|||
property var systemInactive: SystemPalette { colorGroup: SystemPalette.Disabled }
|
||||
property var inactiveColors: currentInactivePalette ? currentInactivePalette : systemInactive
|
||||
property int avatarSize: 40
|
||||
property real highlightHue: colors.highlight.hslHue
|
||||
property real highlightSat: colors.highlight.hslSaturation
|
||||
property real highlightLight: colors.highlight.hslLightness
|
||||
|
||||
palette: colors
|
||||
|
||||
|
|
|
@ -27,6 +27,9 @@ Popup {
|
|||
property alias model: gridView.model
|
||||
property var textArea
|
||||
property string emojiCategory: "people"
|
||||
property real highlightHue: colors.highlight.hslHue
|
||||
property real highlightSat: colors.highlight.hslSaturation
|
||||
property real highlightLight: colors.highlight.hslLightness
|
||||
|
||||
id: emojiPopup
|
||||
|
||||
|
@ -39,6 +42,8 @@ Popup {
|
|||
focus: true
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
|
||||
onPicked: emojiPopup.close()
|
||||
|
||||
ColumnLayout {
|
||||
id: columnView
|
||||
anchors.fill: parent
|
||||
|
@ -98,7 +103,7 @@ Popup {
|
|||
color: "#80000000"
|
||||
source: parent.contentItem
|
||||
}
|
||||
// TODO: emit a signal and maybe add favorites at some point?
|
||||
// TODO: maybe add favorites at some point?
|
||||
onClicked: {
|
||||
console.debug("Picked " + model.unicode + "in response to " + emojiPopup.event_id + " in room " + emojiPopup.room_id)
|
||||
emojiPopup.picked(emojiPopup.room_id, emojiPopup.event_id, model.unicode)
|
||||
|
@ -191,11 +196,8 @@ Popup {
|
|||
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
property real highlightHue: colors.highlight.hslHue
|
||||
property real highlightSat: colors.highlight.hslSaturation
|
||||
property real highlightLight: colors.highlight.hslLightness
|
||||
|
||||
color: emojiPopup.model.category === model.category ? Qt.hsla(highlightHue, highlightSat, highlightLight, 0.25) : 'transparent'
|
||||
color: emojiPopup.model.category === model.category ? Qt.hsla(highlightHue, highlightSat, highlightLight, 0.20) : 'transparent'
|
||||
radius: 5
|
||||
border.color: emojiPopup.model.category === model.category ? colors.highlight : 'transparent'
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ ReactionsModel::roleNames() const
|
|||
{Key, "key"},
|
||||
{Count, "counter"},
|
||||
{Users, "users"},
|
||||
{SelfReacted, "selfReacted"},
|
||||
{SelfReactedEvent, "selfReactedEvent"},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -45,11 +45,11 @@ ReactionsModel::data(const QModelIndex &index, int role) const
|
|||
}
|
||||
return users;
|
||||
}
|
||||
case SelfReacted:
|
||||
case SelfReactedEvent:
|
||||
for (const auto &reaction : reactions[i].reactions)
|
||||
if (reaction.second.sender == http::client()->user_id().to_string())
|
||||
return true;
|
||||
return false;
|
||||
return QString::fromStdString(reaction.second.event_id);
|
||||
return QStringLiteral("");
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
Key,
|
||||
Count,
|
||||
Users,
|
||||
SelfReacted,
|
||||
SelfReactedEvent,
|
||||
};
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
|
|
@ -290,6 +290,22 @@ TimelineViewManager::queueEmoteMessage(const QString &msg)
|
|||
timeline_->sendMessage(emote);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineViewManager::reactToMessage(const QString &roomId,
|
||||
const QString &reactedEvent,
|
||||
const QString &reactionKey,
|
||||
const QString &selfReactedEvent)
|
||||
{
|
||||
// If selfReactedEvent is empty, that means we haven't previously reacted
|
||||
if (selfReactedEvent.isEmpty()) {
|
||||
queueReactionMessage(roomId, reactedEvent, reactionKey);
|
||||
// Otherwise, we have previously reacted and the reaction should be redacted
|
||||
} else {
|
||||
auto model = models.value(roomId);
|
||||
model->redactEvent(selfReactedEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimelineViewManager::queueReactionMessage(const QString &roomId,
|
||||
const QString &reactedEvent,
|
||||
|
|
|
@ -61,6 +61,10 @@ public slots:
|
|||
void queueReactionMessage(const QString &roomId,
|
||||
const QString &reactedEvent,
|
||||
const QString &reaction);
|
||||
void reactToMessage(const QString &roomId,
|
||||
const QString &reactedEvent,
|
||||
const QString &reactionKey,
|
||||
const QString &selfReactedEvent);
|
||||
void queueTextMessage(const QString &msg);
|
||||
void queueEmoteMessage(const QString &msg);
|
||||
void queueImageMessage(const QString &roomid,
|
||||
|
|
Loading…
Reference in a new issue