diff options
-rw-r--r-- | events/event.h | 25 | ||||
-rw-r--r-- | room.cpp | 46 | ||||
-rw-r--r-- | room.h | 18 |
3 files changed, 48 insertions, 41 deletions
diff --git a/events/event.h b/events/event.h index a66f5e68..6b566be0 100644 --- a/events/event.h +++ b/events/event.h @@ -35,7 +35,7 @@ namespace QMatrixClient RoomMessage, RoomName, RoomAliases, RoomCanonicalAlias, RoomMember, RoomTopic, Typing, Receipt, Unknown }; - + class Event { public: @@ -61,28 +61,7 @@ namespace QMatrixClient }; using Events = QVector<Event*>; - Events eventsFromJson(const QJsonArray& contents); - - /** - * Finds a place in the timeline where a new event/message could be inserted. - * @return an iterator to an item with the earliest timestamp after - * the one of 'item'; or timeline.end(), if all events are earlier - */ - template <class ItemT, class ContT> - typename ContT::iterator - findInsertionPos(ContT & timeline, const ItemT *item) - { - return std::lower_bound (timeline.begin(), timeline.end(), item, - [](const typename ContT::value_type a, const ItemT * b) { - // FIXME: We should not order the message list by origin timestamp. - // Rather, an order of receiving should be used (which actually - // poses a question on whether this method is needed at all - - // or we'd just prepend and append, depending on whether we - // received something from /sync or from /messages. - return a->timestamp() < b->timestamp(); - } - ); - } + Events eventsFromJson(const QJsonArray& json); /** * @brief Lookup a value by a key in a varargs list @@ -340,13 +340,14 @@ void Room::updateData(const SyncRoomData& data) processStateEvent(stateEvent); } - for( Event* timelineEvent: data.timeline ) + if (!data.timeline.empty()) { - - processMessageEvent(timelineEvent); - emit newMessage(timelineEvent); - // State changes can arrive in a timeline event - try to check those. - processStateEvent(timelineEvent); + for( Event* e: data.timeline ) + { + // State changes can arrive in a timeline event; so check those. + processStateEvent(e); + } + addNewMessageEvents(data.timeline); } for( Event* ephemeralEvent: data.ephemeral ) @@ -379,11 +380,7 @@ void Room::Private::getPreviousContent() connect( roomMessagesJob, &RoomMessagesJob::result, [=]() { if( !roomMessagesJob->error() ) { - for( Event* event: roomMessagesJob->events() ) - { - q->processMessageEvent(event); - emit q->newMessage(event); - } + q->addHistoricalMessageEvents(roomMessagesJob->events()); prevBatch = roomMessagesJob->end(); } roomMessagesJob = nullptr; @@ -396,9 +393,32 @@ Connection* Room::connection() const return d->connection; } -void Room::processMessageEvent(Event* event) +void Room::addNewMessageEvents(const Events& events) +{ + emit aboutToAddNewMessages(events); + doAddNewMessageEvents(events); + emit addedMessages(); +} + +void Room::doAddNewMessageEvents(const Events& events) +{ + d->messageEvents.reserve(d->messageEvents.size() + events.size()); + std::copy(events.begin(), events.end(), std::back_inserter(d->messageEvents)); +} + +void Room::addHistoricalMessageEvents(const Events& events) +{ + emit aboutToAddHistoricalMessages(events); + doAddHistoricalMessageEvents(events); + emit addedMessages(); +} + +void Room::doAddHistoricalMessageEvents(const Events& events) { - d->messageEvents.insert(findInsertionPos(d->messageEvents, event), event); + // Preserver the order of messages when inserting the block in the + // beginning of the container. + std::reverse_copy(events.begin(), events.end(), + std::front_inserter(d->messageEvents)); } void Room::processStateEvent(Event* event) @@ -82,13 +82,17 @@ namespace QMatrixClient void userRenamed(User* user, QString oldName); signals: - void newMessage(Event* event); + void aboutToAddHistoricalMessages(const Events& events); + void aboutToAddNewMessages(const Events& events); + void addedMessages(); + /** - * Triggered when the room name, canonical alias or other aliases - * change. Not triggered when displayname changes. + * @brief The room name, the canonical alias or other aliases changed + * + * Not triggered when displayname changes. */ void namesChanged(Room* room); - /** Triggered only for changes in the room displayname. */ + /** @brief The room displayname changed */ void displaynameChanged(Room* room); void topicChanged(); void userAdded(User* user); @@ -101,13 +105,17 @@ namespace QMatrixClient protected: Connection* connection() const; - virtual void processMessageEvent(Event* event); + virtual void doAddNewMessageEvents(const Events& events); + virtual void doAddHistoricalMessageEvents(const Events& events); virtual void processStateEvent(Event* event); virtual void processEphemeralEvent(Event* event); private: class Private; Private* d; + + void addNewMessageEvents(const Events& events); + void addHistoricalMessageEvents(const Events& events); }; } |