diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-05-05 19:36:15 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-05-05 19:36:15 +0900 |
commit | a8d2a73c771f188fc0fdc6351b4923af788317d5 (patch) | |
tree | b2795b93149f7c0ae3cd5005331b650a8eb6fd1e /lib/room.cpp | |
parent | da16225dfbec9b155c2c299757203f7676ac6ccf (diff) | |
parent | a63838235134b066c092ad98e1f18ff7991c91c1 (diff) | |
download | libquotient-a8d2a73c771f188fc0fdc6351b4923af788317d5.tar.gz libquotient-a8d2a73c771f188fc0fdc6351b4923af788317d5.zip |
Merge branch 'kitsune-gtad'
Diffstat (limited to 'lib/room.cpp')
-rw-r--r-- | lib/room.cpp | 259 |
1 files changed, 137 insertions, 122 deletions
diff --git a/lib/room.cpp b/lib/room.cpp index a4cfadb4..5f2e3088 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -18,14 +18,15 @@ #include "room.h" -#include "jobs/generated/kicking.h" -#include "jobs/generated/inviting.h" -#include "jobs/generated/banning.h" -#include "jobs/generated/leaving.h" -#include "jobs/generated/receipts.h" -#include "jobs/generated/redaction.h" -#include "jobs/generated/account-data.h" -#include "jobs/setroomstatejob.h" +#include "csapi/kicking.h" +#include "csapi/inviting.h" +#include "csapi/banning.h" +#include "csapi/leaving.h" +#include "csapi/receipts.h" +#include "csapi/redaction.h" +#include "csapi/account-data.h" +#include "csapi/message_pagination.h" +#include "csapi/room_state.h" #include "events/simplestateevents.h" #include "events/roomavatarevent.h" #include "events/roommemberevent.h" @@ -33,7 +34,6 @@ #include "events/receiptevent.h" #include "events/redactionevent.h" #include "jobs/sendeventjob.h" -#include "jobs/roommessagesjob.h" #include "jobs/mediathumbnailjob.h" #include "jobs/downloadfilejob.h" #include "jobs/postreadmarkersjob.h" @@ -112,7 +112,7 @@ class Room::Private TagsMap tags; QHash<QString, AccountDataMap> accountData; QString prevBatch; - QPointer<RoomMessagesJob> roomMessagesJob; + QPointer<GetRoomEventsJob> eventsHistoryJob; struct FileTransferPrivateInfo { @@ -199,13 +199,27 @@ class Room::Private void markMessagesAsRead(rev_iter_t upToMarker); + template <typename EvT> + auto requestSetState(const QString& stateKey, const EvT& event) + { + return connection->callApi<SetRoomStateWithKeyJob>( + id, EvT::typeId(), stateKey, event.toJson()); + } + + template <typename EvT> + auto requestSetState(const EvT& event) + { + return connection->callApi<SetRoomStateJob>( + id, EvT::typeId(), event.toJson()); + } + /** * @brief Apply redaction to the timeline * * Tries to find an event in the timeline and redact it; deletes the * redaction event whether the redacted event was found or not. */ - void processRedaction(RoomEventPtr&& redactionEvent); + void processRedaction(event_ptr_tt<RedactionEvent>&& redaction); void broadcastTagUpdates() { @@ -1036,21 +1050,31 @@ void Room::updateData(SyncRoomData&& data) for (auto&& event: data.accountData) processAccountDataEvent(move(event)); + bool emitNamesChanged = false; if (!data.state.empty()) { et.restart(); - processStateEvents(data.state); - qCDebug(PROFILER) << "*** Room::processStateEvents(state):" + for (const auto& e: data.state) + emitNamesChanged |= processStateEvent(*e); + + qCDebug(PROFILER) << "*** Room::processStateEvents():" << data.state.size() << "event(s)," << et; } if (!data.timeline.empty()) { et.restart(); // State changes can arrive in a timeline event; so check those. - processStateEvents(data.timeline); + for (const auto& e: data.timeline) + emitNamesChanged |= processStateEvent(*e); qCDebug(PROFILER) << "*** Room::processStateEvents(timeline):" << data.timeline.size() << "event(s)," << et; + } + if (emitNamesChanged) + emit namesChanged(this); + d->updateDisplayname(); + if (!data.timeline.empty()) + { et.restart(); d->addNewMessageEvents(move(data.timeline)); qCDebug(PROFILER) << "*** Room::addNewMessageEvents():" << et; @@ -1100,19 +1124,17 @@ void Room::postMessage(const RoomMessageEvent& event) void Room::setName(const QString& newName) { - connection()->callApi<SetRoomStateJob>(id(), RoomNameEvent(newName)); + d->requestSetState(RoomNameEvent(newName)); } void Room::setCanonicalAlias(const QString& newAlias) { - connection()->callApi<SetRoomStateJob>(id(), - RoomCanonicalAliasEvent(newAlias)); + d->requestSetState(RoomCanonicalAliasEvent(newAlias)); } void Room::setTopic(const QString& newTopic) { - RoomTopicEvent evt(newTopic); - connection()->callApi<SetRoomStateJob>(id(), evt); + d->requestSetState(RoomTopicEvent(newTopic)); } void Room::getPreviousContent(int limit) @@ -1122,13 +1144,13 @@ void Room::getPreviousContent(int limit) void Room::Private::getPreviousContent(int limit) { - if( !isJobRunning(roomMessagesJob) ) + if( !isJobRunning(eventsHistoryJob) ) { - roomMessagesJob = - connection->callApi<RoomMessagesJob>(id, prevBatch, limit); - connect( roomMessagesJob, &RoomMessagesJob::success, [=] { - prevBatch = roomMessagesJob->end(); - addHistoricalMessageEvents(roomMessagesJob->releaseEvents()); + eventsHistoryJob = + connection->callApi<GetRoomEventsJob>(id, prevBatch, "b", "", limit); + connect( eventsHistoryJob, &BaseJob::success, q, [=] { + prevBatch = eventsHistoryJob->end(); + addHistoricalMessageEvents(eventsHistoryJob->chunk()); }); } } @@ -1143,6 +1165,11 @@ LeaveRoomJob* Room::leaveRoom() return connection()->callApi<LeaveRoomJob>(id()); } +SetRoomStateWithKeyJob*Room::setMemberState(const QString& memberId, const RoomMemberEvent& event) const +{ + return d->requestSetState(memberId, event); +} + void Room::kickMember(const QString& memberId, const QString& reason) { connection()->callApi<KickJob>(id(), memberId, reason); @@ -1287,11 +1314,8 @@ inline bool isRedaction(const RoomEventPtr& e) return e->type() == EventType::Redaction; } -void Room::Private::processRedaction(RoomEventPtr&& redactionEvent) +void Room::Private::processRedaction(event_ptr_tt<RedactionEvent>&& redaction) { - Q_ASSERT(redactionEvent && isRedaction(redactionEvent)); - const auto& redaction = ptrCast<RedactionEvent>(move(redactionEvent)); - const auto pIdx = eventsIndex.find(redaction->redactedEvent()); if (pIdx == eventsIndex.end()) { @@ -1385,7 +1409,7 @@ void Room::Private::addNewMessageEvents(RoomEvents&& events) const auto normalsBegin = stable_partition(events.begin(), events.end(), isRedaction); RoomEventsRange redactions { events.begin(), normalsBegin }, - normalEvents { normalsBegin, events.end() }; + normalEvents { normalsBegin, events.end() }; if (!normalEvents.empty()) emit q->aboutToAddNewMessages(normalEvents); @@ -1399,7 +1423,10 @@ void Room::Private::addNewMessageEvents(RoomEvents&& events) q->onAddNewTimelineEvents(from); } for (auto&& r: redactions) - processRedaction(move(r)); + { + Q_ASSERT(isRedaction(r)); + processRedaction(ptrCast<RedactionEvent>(move(r))); + } if (insertedSize > 0) { emit q->addedMessages(); @@ -1450,107 +1477,95 @@ void Room::Private::addHistoricalMessageEvents(RoomEvents&& events) Q_ASSERT(timeline.size() == timelineSize + insertedSize); } -void Room::processStateEvents(const RoomEvents& events) +bool Room::processStateEvent(const RoomEvent& e) { - bool emitNamesChanged = false; - for (const auto& e: events) + switch (e.type()) { - switch (e->type()) - { - case EventType::RoomName: { - auto* nameEvent = weakPtr<const RoomNameEvent>(e); - d->name = nameEvent->name(); - qCDebug(MAIN) << "Room name updated:" << d->name; - emitNamesChanged = true; - break; - } - case EventType::RoomAliases: { - auto* aliasesEvent = weakPtr<const RoomAliasesEvent>(e); - d->aliases = aliasesEvent->aliases(); - qCDebug(MAIN) << "Room aliases updated:" << d->aliases; - emitNamesChanged = true; - break; - } - case EventType::RoomCanonicalAlias: { - auto* aliasEvent = weakPtr<const RoomCanonicalAliasEvent>(e); - d->canonicalAlias = aliasEvent->alias(); - setObjectName(d->canonicalAlias); - qCDebug(MAIN) << "Room canonical alias updated:" << d->canonicalAlias; - emitNamesChanged = true; - break; - } - case EventType::RoomTopic: { - auto* topicEvent = weakPtr<const RoomTopicEvent>(e); - d->topic = topicEvent->topic(); - qCDebug(MAIN) << "Room topic updated:" << d->topic; - emit topicChanged(); - break; + case EventType::RoomName: { + d->name = static_cast<const RoomNameEvent&>(e).name(); + qCDebug(MAIN) << "Room name updated:" << d->name; + return true; + } + case EventType::RoomAliases: { + d->aliases = static_cast<const RoomAliasesEvent&>(e).aliases(); + qCDebug(MAIN) << "Room aliases updated:" << d->aliases; + return true; + } + case EventType::RoomCanonicalAlias: { + d->canonicalAlias = + static_cast<const RoomCanonicalAliasEvent&>(e).alias(); + setObjectName(d->canonicalAlias); + qCDebug(MAIN) << "Room canonical alias updated:" << d->canonicalAlias; + return true; + } + case EventType::RoomTopic: { + d->topic = static_cast<const RoomTopicEvent&>(e).topic(); + qCDebug(MAIN) << "Room topic updated:" << d->topic; + emit topicChanged(); + return false; + } + case EventType::RoomAvatar: { + const auto& avatarEventContent = + static_cast<const RoomAvatarEvent&>(e).content(); + if (d->avatar.updateUrl(avatarEventContent.url)) + { + qCDebug(MAIN) << "Room avatar URL updated:" + << avatarEventContent.url.toString(); + emit avatarChanged(); } - case EventType::RoomAvatar: { - const auto& avatarEventContent = - weakPtr<const RoomAvatarEvent>(e)->content(); - if (d->avatar.updateUrl(avatarEventContent.url)) + return false; + } + case EventType::RoomMember: { + const auto& memberEvent = static_cast<const RoomMemberEvent&>(e); + auto* u = user(memberEvent.userId()); + u->processEvent(memberEvent, this); + if (u == localUser() && memberJoinState(u) == JoinState::Invite + && memberEvent.isDirect()) + connection()->addToDirectChats(this, + user(memberEvent.senderId())); + + if( memberEvent.membership() == MembershipType::Join ) + { + if (memberJoinState(u) != JoinState::Join) { - qCDebug(MAIN) << "Room avatar URL updated:" - << avatarEventContent.url.toString(); - emit avatarChanged(); + d->insertMemberIntoMap(u); + connect(u, &User::nameAboutToChange, this, + [=] (QString newName, QString, const Room* context) { + if (context == this) + emit memberAboutToRename(u, newName); + }); + connect(u, &User::nameChanged, this, + [=] (QString, QString oldName, const Room* context) { + if (context == this) + d->renameMember(u, oldName); + }); + emit userAdded(u); } - break; } - case EventType::RoomMember: { - auto* memberEvent = weakPtr<const RoomMemberEvent>(e); - auto u = user(memberEvent->userId()); - u->processEvent(memberEvent, this); - if (u == localUser() && memberJoinState(u) == JoinState::Invite - && memberEvent->isDirect()) - connection()->addToDirectChats(this, - user(memberEvent->senderId())); - - if( memberEvent->membership() == MembershipType::Join ) - { - if (memberJoinState(u) != JoinState::Join) - { - d->insertMemberIntoMap(u); - connect(u, &User::nameAboutToChange, this, - [=] (QString newName, QString, const Room* context) { - if (context == this) - emit memberAboutToRename(u, newName); - }); - connect(u, &User::nameChanged, this, - [=] (QString, QString oldName, const Room* context) { - if (context == this) - d->renameMember(u, oldName); - }); - emit userAdded(u); - } - } - else if( memberEvent->membership() == MembershipType::Leave ) + else if( memberEvent.membership() == MembershipType::Leave ) + { + if (memberJoinState(u) == JoinState::Join) { - if (memberJoinState(u) == JoinState::Join) - { - if (!d->membersLeft.contains(u)) - d->membersLeft.append(u); - d->removeMemberFromMap(u->name(this), u); - emit userRemoved(u); - } + if (!d->membersLeft.contains(u)) + d->membersLeft.append(u); + d->removeMemberFromMap(u->name(this), u); + emit userRemoved(u); } - break; - } - case EventType::RoomEncryption: - { - d->encryptionAlgorithm = - weakPtr<const EncryptionEvent>(e)->algorithm(); - qCDebug(MAIN) << "Encryption switched on in" << displayName(); - emit encryption(); - break; } - default: /* Ignore events of other types */; + return false; } + case EventType::RoomEncryption: + { + d->encryptionAlgorithm = + static_cast<const EncryptionEvent&>(e).algorithm(); + qCDebug(MAIN) << "Encryption switched on in" << displayName(); + emit encryption(); + return false; + } + default: + /* Ignore events of other types */ + return false; } - if (emitNamesChanged) { - emit namesChanged(this); - } - d->updateDisplayname(); } void Room::processEphemeralEvent(EventPtr&& event) @@ -1776,7 +1791,7 @@ void appendEvent(QJsonArray& events, const QString& type, template <typename EvtT> void appendEvent(QJsonArray& events, const EvtT& event) { - appendEvent(events, EvtT::TypeId, event.toJson()); + appendEvent(events, EvtT::typeId(), event.toJson()); } QJsonObject Room::Private::toJson() const |