Changeset View
Changeset View
Standalone View
Standalone View
src/client/room/room-model.cpp
| Show First 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | RoomModel RoomModel::update(RoomModel r, Action a) | ||||
| if (!r.stateEvents.count(k)) { | if (!r.stateEvents.count(k)) { | ||||
| r.stateEvents = std::move(r.stateEvents).set(k, e); | r.stateEvents = std::move(r.stateEvents).set(k, e); | ||||
| } | } | ||||
| } | } | ||||
| return r; | return r; | ||||
| }, | }, | ||||
| [&](AddMessagesAction a) { | [&](AddMessagesAction a) { | ||||
| r.messages = merge(std::move(r.messages), a.events, keyOfTimeline); | r.messages = merge(std::move(r.messages), a.events, keyOfTimeline); | ||||
| if (!a.alsoInTimeline) { | |||||
| for (const auto &e : a.events) { | |||||
| r.nonTimelineEvents = std::move(r.nonTimelineEvents).insert(keyOfTimeline(e)); | |||||
| } | |||||
| } | |||||
| auto handleRedaction = | auto handleRedaction = | ||||
| [&r](const auto &event) { | [&r](const auto &event) { | ||||
| if (event.type() == "m.room.redaction") { | if (event.type() == "m.room.redaction") { | ||||
| auto origJson = event.originalJson().get(); | auto origJson = event.originalJson().get(); | ||||
| if (origJson.contains("redacts") && origJson.at("redacts").is_string()) { | if (origJson.contains("redacts") && origJson.at("redacts").is_string()) { | ||||
| auto redactedEventId = origJson.at("redacts").template get<std::string>(); | auto redactedEventId = origJson.at("redacts").template get<std::string>(); | ||||
| if (r.messages.find(redactedEventId)) { | if (r.messages.find(redactedEventId)) { | ||||
| Show All 31 Lines | RoomModel RoomModel::update(RoomModel r, Action a) | ||||
| return r; | return r; | ||||
| }, | }, | ||||
| [&](AddToTimelineAction a) { | [&](AddToTimelineAction a) { | ||||
| auto eventIds = intoImmer(immer::flex_vector<std::string>(), | auto eventIds = intoImmer(immer::flex_vector<std::string>(), | ||||
| zug::map(keyOfTimeline), a.events); | zug::map(keyOfTimeline), a.events); | ||||
| auto oldMessages = r.messages; | auto oldMessages = r.messages; | ||||
| auto next = RoomModel::update(std::move(r), AddMessagesAction{a.events}); | auto next = RoomModel::update(std::move(r), AddMessagesAction{a.events, /* alsoInTimeline = */ true}); | ||||
| r = std::move(next); | r = std::move(next); | ||||
| auto key = | auto key = | ||||
| [=](auto eventId) { | [=](auto eventId) { | ||||
| // sort first by timestamp, then by id | // sort first by timestamp, then by id | ||||
| return sortKeyForTimelineEvent(r.messages[eventId]); | return sortKeyForTimelineEvent(r.messages[eventId]); | ||||
| }; | }; | ||||
| // Things in messages do not always appear in the timeline. | // Things in messages do not always appear in the timeline. | ||||
| // Let `exists` function to always return false, so that it is checked for duplicates automatically. | // Let `exists` function to always return false, so that it is checked for duplicates automatically. | ||||
| r.timeline = sortedUniqueMerge(r.timeline, eventIds, [](auto &&) { return false; }, key); | r.timeline = sortedUniqueMerge(r.timeline, eventIds, [](auto &&) { return false; }, key); | ||||
| for (const auto &e : eventIds) { | |||||
| r.nonTimelineEvents = std::move(r.nonTimelineEvents).erase(e); | |||||
| } | |||||
| // We have 3 possibilities for the source of calling this action: | // We have 3 possibilities for the source of calling this action: | ||||
| // pagination, sync, or load from storage. | // pagination, sync, or load from storage. | ||||
| // | // | ||||
| // In pagination: `gapEventId.has_value() && !limited.has_value()` | // In pagination: `gapEventId.has_value() && !limited.has_value()` | ||||
| // If we can paginate back: `prevBatch.has_value()` | // If we can paginate back: `prevBatch.has_value()` | ||||
| // | // | ||||
| // In sync: `!gapEventId.has_value()` | // In sync: `!gapEventId.has_value()` | ||||
| // If limited: `limited.has_value() && limited.value()` | // If limited: `limited.has_value() && limited.value()` | ||||
| ▲ Show 20 Lines • Show All 585 Lines • ▼ Show 20 Lines | bool RoomModel::checkInvariants() const | ||||
| && (localReadMarker.empty() || messages.count(localReadMarker)) | && (localReadMarker.empty() || messages.count(localReadMarker)) | ||||
| && std::all_of(reverseEventRelationships.begin(), reverseEventRelationships.end(), [&inMessages](const auto &p) { | && std::all_of(reverseEventRelationships.begin(), reverseEventRelationships.end(), [&inMessages](const auto &p) { | ||||
| const auto &relTypeToEventsMap = p.second; | const auto &relTypeToEventsMap = p.second; | ||||
| return std::all_of(relTypeToEventsMap.begin(), relTypeToEventsMap.end(), [&inMessages](const auto &p2) { | return std::all_of(relTypeToEventsMap.begin(), relTypeToEventsMap.end(), [&inMessages](const auto &p2) { | ||||
| const auto &events = p2.second; | const auto &events = p2.second; | ||||
| return immer::all_of(events, inMessages); | return immer::all_of(events, inMessages); | ||||
| }); | }); | ||||
| }); | }); | ||||
| } | |||||
| bool RoomModel::isInTimeline(const std::string &eventId) const | |||||
| { | |||||
| return !nonTimelineEvents.count(eventId) && messages.count(eventId); | |||||
| } | } | ||||
| } | } | ||||