diff options
Diffstat (limited to 'lib/room.cpp')
-rw-r--r-- | lib/room.cpp | 84 |
1 files changed, 60 insertions, 24 deletions
diff --git a/lib/room.cpp b/lib/room.cpp index bfa6df68..e615060b 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -88,7 +88,7 @@ class Room::Private Connection* connection; Timeline timeline; - RoomEvents unsyncedEvents; + PendingEvents unsyncedEvents; QHash<QString, TimelineItem::index_t> eventsIndex; QString id; QStringList aliases; @@ -207,6 +207,9 @@ class Room::Private return sendEvent(makeEvent<EventT>(std::forward<ArgTs>(eventArgs)...)); } + QString doSendEvent(const RoomEvent* pEvent); + PendingEvents::iterator findAsPending(const RoomEvent* rawEvtPtr); + template <typename EvT> auto requestSetState(const QString& stateKey, const EvT& event) { @@ -250,11 +253,6 @@ class Room::Private } }; -RoomEventPtr TimelineItem::replaceEvent(RoomEventPtr&& other) -{ - return std::exchange(evt, move(other)); -} - Room::Room(Connection* connection, QString id, JoinState initialJoinState) : QObject(connection), d(new Private(connection, id, initialJoinState)) { @@ -283,7 +281,7 @@ const Room::Timeline& Room::messageEvents() const return d->timeline; } -const RoomEvents& Room::pendingEvents() const +const Room::PendingEvents& Room::pendingEvents() const { return d->unsyncedEvents; } @@ -1128,30 +1126,68 @@ void Room::updateData(SyncRoomData&& data) QString Room::Private::sendEvent(RoomEventPtr&& event) { + if (event->transactionId().isEmpty()) + event->setTransactionId(connection->generateTxnId()); auto* pEvent = rawPtr(event); emit q->pendingEventAboutToAdd(); unsyncedEvents.emplace_back(move(event)); emit q->pendingEventAdded(); + return doSendEvent(pEvent); +} - if (pEvent->transactionId().isEmpty()) - pEvent->setTransactionId(connection->generateTxnId()); +QString Room::Private::doSendEvent(const RoomEvent* pEvent) +{ + auto txnId = pEvent->transactionId(); // TODO: Enqueue the job rather than immediately trigger it - auto call = connection->sendMessage(id, *pEvent); - Room::connect(call, &BaseJob::success, q, [this,call,pEvent] - { - const auto comparator = - [pEvent] (const auto& eptr) { return rawPtr(eptr) == pEvent; }; + auto call = connection->callApi<SendMessageJob>(BackgroundRequest, + id, pEvent->matrixType(), txnId, pEvent->contentJson()); + Room::connect(call, &BaseJob::started, q, + [this,pEvent,txnId] { + auto it = findAsPending(pEvent); + if (it == unsyncedEvents.end()) + { + qWarning(EVENTS) << "Pending event for transaction" << txnId + << "not found - got synced so soon?"; + return; + } + it->setDeparted(); + emit q->pendingEventChanged(it - unsyncedEvents.begin()); + }); + Room::connect(call, &BaseJob::failure, q, + [this,pEvent,txnId,call] { + auto it = findAsPending(pEvent); + if (it == unsyncedEvents.end()) + { + qCritical(EVENTS) << "Pending event for transaction" << txnId + << "got lost without successful sending"; + return; + } + it->setSendingFailed( + call->statusCaption() % ": " % call->errorString()); + emit q->pendingEventChanged(it - unsyncedEvents.begin()); + + }); + Room::connect(call, &BaseJob::success, q, + [this,call,pEvent] { + // Find an event by the pointer saved in the lambda (the pointer + // may be dangling by now but we can still search by it). + auto it = findAsPending(pEvent); + if (it == unsyncedEvents.end()) + return; // The event is already synced, nothing to do + + it->setReachedServer(call->eventId()); + emit q->pendingEventChanged(it - unsyncedEvents.begin()); + }); + return txnId; +} - // Find an event by the pointer saved in the lambda - auto it = std::find_if(unsyncedEvents.begin(), unsyncedEvents.end(), - comparator); - if (it == unsyncedEvents.end()) - return; // The event is already synced, nothing to do +Room::PendingEvents::iterator Room::Private::findAsPending( + const RoomEvent* rawEvtPtr) +{ + const auto comp = + [rawEvtPtr] (const auto& pe) { return pe.event() == rawEvtPtr; }; - pEvent->addId(call->eventId()); - emit q->pendingEventChanged(it - unsyncedEvents.begin()); - }); - return pEvent->transactionId(); + return std::find_if(unsyncedEvents.begin(), unsyncedEvents.end(), comp); } QString Room::postMessage(const QString& type, const QString& plainText) @@ -1202,7 +1238,7 @@ void Room::setTopic(const QString& newTopic) d->requestSetState(RoomTopicEvent(newTopic)); } -bool isEchoEvent(const RoomEventPtr& le, const RoomEventPtr& re) +bool isEchoEvent(const RoomEventPtr& le, const PendingEventItem& re) { if (le->type() != re->type()) return false; |