mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-12-01 14:58:47 +03:00
Use templates for the TimelineItem generation
This commit is contained in:
parent
deb1a6e292
commit
5663c58dd9
2 changed files with 90 additions and 139 deletions
|
@ -18,6 +18,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QDebug>
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
|
@ -90,15 +91,6 @@ public:
|
||||||
const QString &room_id,
|
const QString &room_id,
|
||||||
QWidget *parent = 0);
|
QWidget *parent = 0);
|
||||||
|
|
||||||
// For events with custom display widgets.
|
|
||||||
template<class Event, class Widget>
|
|
||||||
TimelineItem *createTimelineItem(const Event &event, bool withSender);
|
|
||||||
|
|
||||||
// For events without custom display widgets.
|
|
||||||
// TODO: All events should have custom widgets.
|
|
||||||
template<class Event>
|
|
||||||
TimelineItem *createTimelineItem(const Event &event, bool withSender);
|
|
||||||
|
|
||||||
// Add new events at the end of the timeline.
|
// Add new events at the end of the timeline.
|
||||||
int addEvents(const Timeline &timeline);
|
int addEvents(const Timeline &timeline);
|
||||||
void addUserMessage(matrix::events::MessageEventType ty, const QString &msg);
|
void addUserMessage(matrix::events::MessageEventType ty, const QString &msg);
|
||||||
|
@ -141,6 +133,22 @@ private:
|
||||||
void readLastEvent() const;
|
void readLastEvent() const;
|
||||||
QString getLastEventId() const;
|
QString getLastEventId() const;
|
||||||
|
|
||||||
|
template<class Event, class Widget>
|
||||||
|
TimelineItem *processMessageEvent(const QJsonObject &event, TimelineDirection direction);
|
||||||
|
|
||||||
|
// TODO: Remove this eventually.
|
||||||
|
template<class Event>
|
||||||
|
TimelineItem *processMessageEvent(const QJsonObject &event, TimelineDirection direction);
|
||||||
|
|
||||||
|
// For events with custom display widgets.
|
||||||
|
template<class Event, class Widget>
|
||||||
|
TimelineItem *createTimelineItem(const Event &event, bool withSender);
|
||||||
|
|
||||||
|
// For events without custom display widgets.
|
||||||
|
// TODO: All events should have custom widgets.
|
||||||
|
template<class Event>
|
||||||
|
TimelineItem *createTimelineItem(const Event &event, bool withSender);
|
||||||
|
|
||||||
// Used to determine whether or not we should prefix a message with the
|
// Used to determine whether or not we should prefix a message with the
|
||||||
// sender's name.
|
// sender's name.
|
||||||
bool isSenderRendered(const QString &user_id, TimelineDirection direction);
|
bool isSenderRendered(const QString &user_id, TimelineDirection direction);
|
||||||
|
@ -238,3 +246,65 @@ TimelineView::createTimelineItem(const Event &event, bool withSender)
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Event>
|
||||||
|
TimelineItem *
|
||||||
|
TimelineView::processMessageEvent(const QJsonObject &data, TimelineDirection direction)
|
||||||
|
{
|
||||||
|
Event event;
|
||||||
|
|
||||||
|
try {
|
||||||
|
event.deserialize(data);
|
||||||
|
} catch (const DeserializationException &e) {
|
||||||
|
qWarning() << e.what() << data;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDuplicate(event.eventId()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
eventIds_[event.eventId()] = true;
|
||||||
|
|
||||||
|
QString txnid = event.unsignedData().transactionId();
|
||||||
|
if (!txnid.isEmpty() && isPendingMessage(txnid, event.sender(), local_user_)) {
|
||||||
|
removePendingMessage(txnid);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto with_sender = isSenderRendered(event.sender(), direction);
|
||||||
|
|
||||||
|
updateLastSender(event.sender(), direction);
|
||||||
|
|
||||||
|
return createTimelineItem<Event>(event, with_sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Event, class Widget>
|
||||||
|
TimelineItem *
|
||||||
|
TimelineView::processMessageEvent(const QJsonObject &data, TimelineDirection direction)
|
||||||
|
{
|
||||||
|
Event event;
|
||||||
|
|
||||||
|
try {
|
||||||
|
event.deserialize(data);
|
||||||
|
} catch (const DeserializationException &e) {
|
||||||
|
qWarning() << e.what() << data;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDuplicate(event.eventId()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
eventIds_[event.eventId()] = true;
|
||||||
|
|
||||||
|
QString txnid = event.unsignedData().transactionId();
|
||||||
|
if (!txnid.isEmpty() && isPendingMessage(txnid, event.sender(), local_user_)) {
|
||||||
|
removePendingMessage(txnid);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto with_sender = isSenderRendered(event.sender(), direction);
|
||||||
|
|
||||||
|
updateLastSender(event.sender(), direction);
|
||||||
|
|
||||||
|
return createTimelineItem<Event, Widget>(event, with_sender);
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDebug>
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
@ -229,140 +228,22 @@ TimelineView::parseMessageEvent(const QJsonObject &event, TimelineDirection dire
|
||||||
if (ty == events::EventType::RoomMessage) {
|
if (ty == events::EventType::RoomMessage) {
|
||||||
events::MessageEventType msg_type = events::extractMessageEventType(event);
|
events::MessageEventType msg_type = events::extractMessageEventType(event);
|
||||||
|
|
||||||
if (msg_type == events::MessageEventType::Text) {
|
|
||||||
events::MessageEvent<msgs::Text> text;
|
|
||||||
|
|
||||||
try {
|
|
||||||
text.deserialize(event);
|
|
||||||
} catch (const DeserializationException &e) {
|
|
||||||
qWarning() << e.what() << event;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDuplicate(text.eventId()))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
eventIds_[text.eventId()] = true;
|
|
||||||
|
|
||||||
QString txnid = text.unsignedData().transactionId();
|
|
||||||
if (!txnid.isEmpty() &&
|
|
||||||
isPendingMessage(txnid, text.sender(), local_user_)) {
|
|
||||||
removePendingMessage(txnid);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto with_sender = isSenderRendered(text.sender(), direction);
|
|
||||||
|
|
||||||
updateLastSender(text.sender(), direction);
|
|
||||||
|
|
||||||
using Text = events::MessageEvent<msgs::Text>;
|
|
||||||
return createTimelineItem<Text>(text, with_sender);
|
|
||||||
} else if (msg_type == events::MessageEventType::Notice) {
|
|
||||||
events::MessageEvent<msgs::Notice> notice;
|
|
||||||
|
|
||||||
try {
|
|
||||||
notice.deserialize(event);
|
|
||||||
} catch (const DeserializationException &e) {
|
|
||||||
qWarning() << e.what() << event;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDuplicate(notice.eventId()))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
eventIds_[notice.eventId()] = true;
|
|
||||||
|
|
||||||
auto with_sender = isSenderRendered(notice.sender(), direction);
|
|
||||||
|
|
||||||
updateLastSender(notice.sender(), direction);
|
|
||||||
|
|
||||||
using Notice = events::MessageEvent<msgs::Notice>;
|
|
||||||
return createTimelineItem<Notice>(notice, with_sender);
|
|
||||||
} else if (msg_type == events::MessageEventType::Image) {
|
|
||||||
events::MessageEvent<msgs::Image> img;
|
|
||||||
|
|
||||||
try {
|
|
||||||
img.deserialize(event);
|
|
||||||
} catch (const DeserializationException &e) {
|
|
||||||
qWarning() << e.what() << event;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDuplicate(img.eventId()))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
eventIds_[img.eventId()] = true;
|
|
||||||
|
|
||||||
QString txnid = img.unsignedData().transactionId();
|
|
||||||
if (!txnid.isEmpty() &&
|
|
||||||
isPendingMessage(txnid, img.sender(), local_user_)) {
|
|
||||||
removePendingMessage(txnid);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto with_sender = isSenderRendered(img.sender(), direction);
|
|
||||||
|
|
||||||
updateLastSender(img.sender(), direction);
|
|
||||||
|
|
||||||
using Image = events::MessageEvent<msgs::Image>;
|
|
||||||
return createTimelineItem<Image, ImageItem>(img, with_sender);
|
|
||||||
} else if (msg_type == events::MessageEventType::Emote) {
|
|
||||||
events::MessageEvent<msgs::Emote> emote;
|
|
||||||
|
|
||||||
try {
|
|
||||||
emote.deserialize(event);
|
|
||||||
} catch (const DeserializationException &e) {
|
|
||||||
qWarning() << e.what() << event;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDuplicate(emote.eventId()))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
eventIds_[emote.eventId()] = true;
|
|
||||||
|
|
||||||
QString txnid = emote.unsignedData().transactionId();
|
|
||||||
if (!txnid.isEmpty() &&
|
|
||||||
isPendingMessage(txnid, emote.sender(), local_user_)) {
|
|
||||||
removePendingMessage(txnid);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto with_sender = isSenderRendered(emote.sender(), direction);
|
|
||||||
|
|
||||||
updateLastSender(emote.sender(), direction);
|
|
||||||
|
|
||||||
using Emote = events::MessageEvent<msgs::Emote>;
|
using Emote = events::MessageEvent<msgs::Emote>;
|
||||||
return createTimelineItem<Emote>(emote, with_sender);
|
|
||||||
} else if (msg_type == events::MessageEventType::File) {
|
|
||||||
events::MessageEvent<msgs::File> file;
|
|
||||||
|
|
||||||
try {
|
|
||||||
file.deserialize(event);
|
|
||||||
} catch (const DeserializationException &e) {
|
|
||||||
qWarning() << e.what() << event;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDuplicate(file.eventId()))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
eventIds_[file.eventId()] = true;
|
|
||||||
|
|
||||||
QString txnid = file.unsignedData().transactionId();
|
|
||||||
|
|
||||||
if (!txnid.isEmpty() &&
|
|
||||||
isPendingMessage(txnid, file.sender(), local_user_)) {
|
|
||||||
removePendingMessage(txnid);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto withSender = isSenderRendered(file.sender(), direction);
|
|
||||||
|
|
||||||
updateLastSender(file.sender(), direction);
|
|
||||||
|
|
||||||
using File = events::MessageEvent<msgs::File>;
|
using File = events::MessageEvent<msgs::File>;
|
||||||
return createTimelineItem<File, FileItem>(file, withSender);
|
using Image = events::MessageEvent<msgs::Image>;
|
||||||
|
using Notice = events::MessageEvent<msgs::Notice>;
|
||||||
|
using Text = events::MessageEvent<msgs::Text>;
|
||||||
|
|
||||||
|
if (msg_type == events::MessageEventType::Text) {
|
||||||
|
return processMessageEvent<Text>(event, direction);
|
||||||
|
} else if (msg_type == events::MessageEventType::Notice) {
|
||||||
|
return processMessageEvent<Notice>(event, direction);
|
||||||
|
} else if (msg_type == events::MessageEventType::Image) {
|
||||||
|
return processMessageEvent<Image, ImageItem>(event, direction);
|
||||||
|
} else if (msg_type == events::MessageEventType::Emote) {
|
||||||
|
return processMessageEvent<Emote>(event, direction);
|
||||||
|
} else if (msg_type == events::MessageEventType::File) {
|
||||||
|
return processMessageEvent<File, FileItem>(event, direction);
|
||||||
} else if (msg_type == events::MessageEventType::Unknown) {
|
} else if (msg_type == events::MessageEventType::Unknown) {
|
||||||
// TODO Handle redacted messages.
|
// TODO Handle redacted messages.
|
||||||
// Silenced for now.
|
// Silenced for now.
|
||||||
|
|
Loading…
Reference in a new issue