Compare commits
1 Commits
master
...
work/redst
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea18152fad |
@@ -25,6 +25,7 @@ ReactionModel::ReactionModel(MessageContentModel *parent, const QString &eventId
|
|||||||
Q_ASSERT(room != nullptr);
|
Q_ASSERT(room != nullptr);
|
||||||
|
|
||||||
connect(m_room, &NeoChatRoom::updatedEvent, this, [this](const QString &eventId) {
|
connect(m_room, &NeoChatRoom::updatedEvent, this, [this](const QString &eventId) {
|
||||||
|
m_queuedEvents.clear();
|
||||||
if (m_eventId == eventId) {
|
if (m_eventId == eventId) {
|
||||||
updateReactions();
|
updateReactions();
|
||||||
}
|
}
|
||||||
@@ -115,36 +116,44 @@ void ReactionModel::updateReactions()
|
|||||||
m_shortcodes.clear();
|
m_shortcodes.clear();
|
||||||
|
|
||||||
const auto &annotations = m_room->relatedEvents(m_eventId, Quotient::EventRelation::AnnotationType);
|
const auto &annotations = m_room->relatedEvents(m_eventId, Quotient::EventRelation::AnnotationType);
|
||||||
if (annotations.isEmpty()) {
|
auto &pendingEvents = m_queuedEvents;
|
||||||
|
if (annotations.isEmpty() && pendingEvents.empty()) {
|
||||||
endResetModel();
|
endResetModel();
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
|
|
||||||
QMap<QString, QStringList> reactions = {};
|
QMap<QString, QStringList> reactions = {};
|
||||||
|
|
||||||
|
const auto addReaction = [this, &reactions](const Quotient::ReactionEvent *e) {
|
||||||
|
reactions[e->key()].append(e->senderId());
|
||||||
|
if (e->contentJson()[QStringLiteral("shortcode")].toString().length()) {
|
||||||
|
m_shortcodes[e->key()] = e->contentJson()[QStringLiteral("shortcode")].toString().toHtmlEscaped();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (const auto &a : annotations) {
|
for (const auto &a : annotations) {
|
||||||
if (a->isRedacted()) { // Just in case?
|
if (a->isRedacted()) { // Just in case?
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (const auto &e = eventCast<const Quotient::ReactionEvent>(a)) {
|
if (const auto &e = eventCast<const Quotient::ReactionEvent>(a)) {
|
||||||
reactions[e->key()].append(e->senderId());
|
addReaction(e);
|
||||||
if (e->contentJson()["shortcode"_L1].toString().length()) {
|
|
||||||
m_shortcodes[e->key()] = e->contentJson()["shortcode"_L1].toString().toHtmlEscaped();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto &e : pendingEvents) {
|
||||||
|
if (e->isRedacted()) { // Just in case?
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
addReaction(e);
|
||||||
|
}
|
||||||
|
|
||||||
if (reactions.isEmpty()) {
|
if (reactions.isEmpty()) {
|
||||||
endResetModel();
|
endResetModel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto i = reactions.constBegin();
|
auto i = reactions.constBegin();
|
||||||
while (i != reactions.constEnd()) {
|
while (i != reactions.constEnd()) {
|
||||||
QStringList members;
|
m_reactions.append(ReactionModel::Reaction{i.key(), i.value()});
|
||||||
for (const auto &member : i.value()) {
|
|
||||||
members.append(member);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_reactions.append(ReactionModel::Reaction{i.key(), members});
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,6 +170,12 @@ QHash<int, QByteArray> ReactionModel::roleNames() const
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReactionModel::queueReaction(const Quotient::ReactionEvent *event)
|
||||||
|
{
|
||||||
|
m_queuedEvents.push_back(event);
|
||||||
|
updateReactions();
|
||||||
|
}
|
||||||
|
|
||||||
QString ReactionModel::reactionText(QString text) const
|
QString ReactionModel::reactionText(QString text) const
|
||||||
{
|
{
|
||||||
text = text.toHtmlEscaped();
|
text = text.toHtmlEscaped();
|
||||||
|
|||||||
@@ -70,6 +70,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Puts a ReactionEvent into the pending queue. This reaction should be pulled from the pending queue.
|
||||||
|
*
|
||||||
|
* This queue is cleared once the message is updated.
|
||||||
|
*
|
||||||
|
* @param event The ReactionEvent to add.
|
||||||
|
*/
|
||||||
|
void queueReaction(const Quotient::ReactionEvent *event);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
* @brief The reactions in the model have been updated.
|
* @brief The reactions in the model have been updated.
|
||||||
@@ -81,6 +90,7 @@ private:
|
|||||||
QString m_eventId;
|
QString m_eventId;
|
||||||
QList<Reaction> m_reactions;
|
QList<Reaction> m_reactions;
|
||||||
QMap<QString, QString> m_shortcodes;
|
QMap<QString, QString> m_shortcodes;
|
||||||
|
QList<const Quotient::ReactionEvent *> m_queuedEvents;
|
||||||
|
|
||||||
void updateReactions();
|
void updateReactions();
|
||||||
QString reactionText(QString text) const;
|
QString reactionText(QString text) const;
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ void MessageModel::refreshLastUserEvents(int baseTimelineRow)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageModel::createEventObjects(const Quotient::RoomEvent *event)
|
void MessageModel::createEventObjects(const Quotient::RoomEvent *event, bool pending)
|
||||||
{
|
{
|
||||||
if (event == nullptr) {
|
if (event == nullptr) {
|
||||||
return;
|
return;
|
||||||
@@ -469,6 +469,28 @@ void MessageModel::createEventObjects(const Quotient::RoomEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pending) {
|
||||||
|
if (const auto reactionEvent = eventCast<const ReactionEvent>(event)) {
|
||||||
|
auto targetEvent = m_currentRoom->getEvent(reactionEvent->eventId());
|
||||||
|
if (!targetEvent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto roomEvent = eventCast<const RoomMessageEvent>(targetEvent)) {
|
||||||
|
if (m_reactionModels.contains(targetEvent->id())) {
|
||||||
|
m_reactionModels[targetEvent->id()]->queueReaction(reactionEvent);
|
||||||
|
} else {
|
||||||
|
auto reactionModel = QSharedPointer<ReactionModel>(new ReactionModel(roomEvent, m_currentRoom));
|
||||||
|
m_reactionModels[targetEvent->id()] = reactionModel;
|
||||||
|
reactionModel->queueReaction(reactionEvent);
|
||||||
|
if (!resetting) {
|
||||||
|
refreshEventRoles(targetEvent->id(), {ReactionRole, ShowReactionsRole});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageModel::moveReadMarker(const QString &toEventId)
|
void MessageModel::moveReadMarker(const QString &toEventId)
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
QMap<QString, QSharedPointer<ReadMarkerModel>> m_readMarkerModels;
|
QMap<QString, QSharedPointer<ReadMarkerModel>> m_readMarkerModels;
|
||||||
|
|
||||||
void createEventObjects(const Quotient::RoomEvent *event);
|
void createEventObjects(const Quotient::RoomEvent *event, bool pending);
|
||||||
|
|
||||||
static std::function<bool(const Quotient::RoomEvent *)> m_hiddenFilter;
|
static std::function<bool(const Quotient::RoomEvent *)> m_hiddenFilter;
|
||||||
static bool m_threadsEnabled;
|
static bool m_threadsEnabled;
|
||||||
|
|||||||
Reference in New Issue
Block a user