diff --git a/include/TimelineView.h b/include/TimelineView.h index 5453ea5c..898a304e 100644 --- a/include/TimelineView.h +++ b/include/TimelineView.h @@ -18,6 +18,7 @@ #pragma once #include +#include #include #include #include @@ -90,15 +91,6 @@ public: const QString &room_id, QWidget *parent = 0); - // For events with custom display widgets. - template - TimelineItem *createTimelineItem(const Event &event, bool withSender); - - // For events without custom display widgets. - // TODO: All events should have custom widgets. - template - TimelineItem *createTimelineItem(const Event &event, bool withSender); - // Add new events at the end of the timeline. int addEvents(const Timeline &timeline); void addUserMessage(matrix::events::MessageEventType ty, const QString &msg); @@ -141,6 +133,22 @@ private: void readLastEvent() const; QString getLastEventId() const; + template + TimelineItem *processMessageEvent(const QJsonObject &event, TimelineDirection direction); + + // TODO: Remove this eventually. + template + TimelineItem *processMessageEvent(const QJsonObject &event, TimelineDirection direction); + + // For events with custom display widgets. + template + TimelineItem *createTimelineItem(const Event &event, bool withSender); + + // For events without custom display widgets. + // TODO: All events should have custom widgets. + template + TimelineItem *createTimelineItem(const Event &event, bool withSender); + // Used to determine whether or not we should prefix a message with the // sender's name. bool isSenderRendered(const QString &user_id, TimelineDirection direction); @@ -238,3 +246,65 @@ TimelineView::createTimelineItem(const Event &event, bool withSender) return item; } + +template +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, with_sender); +} + +template +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, with_sender); +} diff --git a/src/TimelineView.cc b/src/TimelineView.cc index e61307fa..7bbda051 100644 --- a/src/TimelineView.cc +++ b/src/TimelineView.cc @@ -16,7 +16,6 @@ */ #include -#include #include #include @@ -229,140 +228,22 @@ TimelineView::parseMessageEvent(const QJsonObject &event, TimelineDirection dire if (ty == events::EventType::RoomMessage) { events::MessageEventType msg_type = events::extractMessageEventType(event); + using Emote = events::MessageEvent; + using File = events::MessageEvent; + using Image = events::MessageEvent; + using Notice = events::MessageEvent; + using Text = events::MessageEvent; + if (msg_type == events::MessageEventType::Text) { - events::MessageEvent 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; - return createTimelineItem(text, with_sender); + return processMessageEvent(event, direction); } else if (msg_type == events::MessageEventType::Notice) { - events::MessageEvent 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; - return createTimelineItem(notice, with_sender); + return processMessageEvent(event, direction); } else if (msg_type == events::MessageEventType::Image) { - events::MessageEvent 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; - return createTimelineItem(img, with_sender); + return processMessageEvent(event, direction); } else if (msg_type == events::MessageEventType::Emote) { - events::MessageEvent 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; - return createTimelineItem(emote, with_sender); + return processMessageEvent(event, direction); } else if (msg_type == events::MessageEventType::File) { - events::MessageEvent 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; - return createTimelineItem(file, withSender); + return processMessageEvent(event, direction); } else if (msg_type == events::MessageEventType::Unknown) { // TODO Handle redacted messages. // Silenced for now.