Changeset View
Changeset View
Standalone View
Standalone View
src/client/client-model.cpp
| Show All 37 Lines | |||||
| namespace Kazv | namespace Kazv | ||||
| { | { | ||||
| auto ClientModel::update(ClientModel m, Action a) -> Result | auto ClientModel::update(ClientModel m, Action a) -> Result | ||||
| { | { | ||||
| auto oldClient = m; | auto oldClient = m; | ||||
| auto oldDeviceLists = m.deviceLists; | auto oldDeviceLists = m.deviceLists; | ||||
| auto actionIsStorage = std::holds_alternative<LoadEventsFromStorageAction>(a) || std::holds_alternative<PurgeRoomTimelineAction>(a); | |||||
| auto [newClient, effect] = lager::match(std::move(a))( | auto [newClient, effect] = lager::match(std::move(a))( | ||||
| [&](RoomListAction a) -> Result { | [&](RoomListAction a) -> Result { | ||||
| m.roomList = RoomListModel::update(std::move(m.roomList), a); | m.roomList = RoomListModel::update(std::move(m.roomList), a); | ||||
| return {std::move(m), lager::noop}; | return {std::move(m), lager::noop}; | ||||
| }, | }, | ||||
| [&](ResubmitJobAction a) -> Result { | [&](ResubmitJobAction a) -> Result { | ||||
| m.addJob(std::move(a.job)); | m.addJob(std::move(a.job)); | ||||
| return { std::move(m), lager::noop }; | return { std::move(m), lager::noop }; | ||||
| ▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | #define RESPONSE_FOR(_jobId) \ | ||||
| return { std::move(m), lager::noop }; | return { std::move(m), lager::noop }; | ||||
| } | } | ||||
| #undef RESPONSE_FOR | #undef RESPONSE_FOR | ||||
| ); | ); | ||||
| newClient.maybeRotateSessions(oldClient); | newClient.maybeRotateSessions(oldClient); | ||||
| // if it is an storage action, do not add it back because the things | |||||
| // should be the same as the ones in storage | |||||
| if (!actionIsStorage) { | |||||
| newClient.maybeAddSaveEventsTrigger(oldClient); | |||||
| } | |||||
| return { std::move(newClient), std::move(effect) }; | return { std::move(newClient), std::move(effect) }; | ||||
| } | } | ||||
| std::pair<Event, std::optional<std::string>> ClientModel::megOlmEncrypt( | std::pair<Event, std::optional<std::string>> ClientModel::megOlmEncrypt( | ||||
| Event e, std::string roomId, Timestamp timeMs, RandomData random) | Event e, std::string roomId, Timestamp timeMs, RandomData random) | ||||
| { | { | ||||
| if (!crypto) { | if (!crypto) { | ||||
| kzo.client.dbg() << "We do not have e2ee, so do not encrypt events" << std::endl; | kzo.client.dbg() << "We do not have e2ee, so do not encrypt events" << std::endl; | ||||
| ▲ Show 20 Lines • Show All 286 Lines • ▼ Show 20 Lines | auto ClientModel::roomIdsByTagId() const -> immer::map<std::string, immer::map<std::string, double>> | ||||
| return acc; | return acc; | ||||
| } | } | ||||
| ); | ); | ||||
| } | } | ||||
| const Crypto &ClientModel::constCrypto() const | const Crypto &ClientModel::constCrypto() const | ||||
| { | { | ||||
| return crypto.value().get(); | return crypto.value().get(); | ||||
| } | |||||
| void ClientModel::maybeAddSaveEventsTrigger(const ClientModel &old) | |||||
| { | |||||
| SaveEventsRequested trigger; | |||||
| using ELT = immer::flex_vector_transient<Event>; | |||||
| auto addToTrigger = [&trigger](const std::string &roomId, ELT tl, ELT nonTl) { | |||||
| if (!tl.empty()) { | |||||
| trigger.timelineEvents = std::move(trigger.timelineEvents).set(roomId, std::move(tl).persistent()); | |||||
| } | |||||
| if (!nonTl.empty()) { | |||||
| trigger.nonTimelineEvents = std::move(trigger.nonTimelineEvents).set(roomId, std::move(nonTl).persistent()); | |||||
| } | |||||
| }; | |||||
| immer::diff(old.roomList.rooms, roomList.rooms, immer::make_differ( | |||||
| /* addedFn = */ [&addToTrigger](const auto &p) { | |||||
| const auto &[roomId, room] = p; | |||||
| ELT tl; | |||||
| ELT nonTl; | |||||
| for (const auto &[id, e] : room.messages) { | |||||
| if (room.isInTimeline(id)) { | |||||
| tl.push_back(e); | |||||
| } else { | |||||
| nonTl.push_back(e); | |||||
| } | |||||
| } | |||||
| addToTrigger(roomId, std::move(tl), std::move(nonTl)); | |||||
| }, | |||||
| /* removedFn = */ [](auto &&) {}, | |||||
| /* changedFn = */ [&addToTrigger](const auto &p1, const auto &p2) { | |||||
| const auto &roomId = p2.first; | |||||
| const auto &newRoom = p2.second; | |||||
| const auto &oldRoom = p1.second; | |||||
| ELT tl; | |||||
| ELT nonTl; | |||||
| auto addEvent = [&tl, &nonTl, &newRoom](const auto &newPair) { | |||||
| const auto &[eventId, event] = newPair; | |||||
| if (newRoom.isInTimeline(eventId)) { | |||||
| tl.push_back(event); | |||||
| } else { | |||||
| nonTl.push_back(event); | |||||
| } | |||||
| }; | |||||
| immer::diff(oldRoom.messages, newRoom.messages, immer::make_differ( | |||||
| /* addedFn = */ addEvent, | |||||
| /* removedFn = */ [](auto &&) {}, | |||||
| /* changedFn = */ [&addEvent](auto &&, auto &&newPair) { | |||||
| addEvent(std::forward<decltype(newPair)>(newPair)); | |||||
| } | |||||
| )); | |||||
| addToTrigger(roomId, std::move(tl), std::move(nonTl)); | |||||
| } | |||||
| )); | |||||
| if (!trigger.timelineEvents.empty() || !trigger.nonTimelineEvents.empty()) { | |||||
| nextTriggers = std::move(nextTriggers).push_back(trigger); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||