libkazv
Loading...
Searching...
No Matches
room-model.hpp
Go to the documentation of this file.
1/*
2 * This file is part of libkazv.
3 * SPDX-FileCopyrightText: 2021-2023 tusooa <tusooa@kazv.moe>
4 * SPDX-License-Identifier: AGPL-3.0-or-later
5 */
6
7
8#pragma once
9#include <libkazv-config.hpp>
10
11#include <string>
12#include <variant>
13#include <immer/flex_vector.hpp>
14#include <immer/map.hpp>
15#include <immer/set.hpp>
16
22
23#include <csapi/sync.hpp>
24#include <event.hpp>
25
26#include <crypto.hpp>
27#include "push-rules-desc.hpp"
28#include "local-echo.hpp"
29#include "clientutil.hpp"
30
31namespace Kazv
32{
34 {
35 std::string txnId;
36 immer::map<std::string, immer::map<std::string, Event>> messages;
37
38 friend bool operator==(const PendingRoomKeyEvent &a, const PendingRoomKeyEvent &b) = default;
39 friend bool operator!=(const PendingRoomKeyEvent &a, const PendingRoomKeyEvent &b) = default;
40 };
41
42 PendingRoomKeyEvent makePendingRoomKeyEventV0(std::string txnId, Event event, immer::map<std::string, immer::flex_vector<std::string>> devices);
43
45 {
46 std::string eventId;
48 friend bool operator==(const ReadReceipt &a, const ReadReceipt &b) = default;
49 friend bool operator!=(const ReadReceipt &a, const ReadReceipt &b) = default;
50 };
51
52 template<class Archive>
53 void serialize(Archive &ar, ReadReceipt &r, std::uint32_t const /* version */)
54 {
55 ar & r.eventId & r.timestamp;
56 }
57
58
60 {
61 std::string userId;
63 friend bool operator==(const EventReader &a, const EventReader &b) = default;
64 friend bool operator!=(const EventReader &a, const EventReader &b) = default;
65 };
66
68 {
69 immer::flex_vector<Event> stateEvents;
70 };
71
76 {
77 immer::flex_vector<Event> stateEvents;
78 };
79
83 {
86 bool alsoInTimeline{false};
87 };
88
90 {
92 immer::flex_vector<Event> events;
93 std::optional<std::string> prevBatch;
94 std::optional<bool> limited;
95 std::optional<std::string> gapEventId;
96 };
97
99 {
100 immer::flex_vector<Event> events;
101 };
102
107
109 {
110 immer::flex_vector<Event> events;
111 };
112
117
119 {
120 std::string localDraft;
121 };
122
124 {
125 };
126
128 {
129 };
130
132 {
133 immer::flex_vector<std::string> heroIds;
134 };
135
140
142 {
143 std::string txnId;
144 };
145
150
152 {
153 std::string txnId;
154 };
155
157 {
158 std::size_t joinedMemberCount;
159 };
160
165
175
178 {
179 std::string myUserId;
180 };
181
184 {
185 std::string localReadMarker;
186 std::string myUserId;
187 };
188
191 {
192 std::size_t maxToKeep;
193 };
194
195 inline const double ROOM_TAG_DEFAULT_ORDER = 2;
196
197 template<class Archive>
198 void serialize(Archive &ar, PendingRoomKeyEvent &e, std::uint32_t const version)
199 {
200 if (version < 1) {
201 // loading an older version where there is only one event
202 std::string txnId;
203 Event event;
204 immer::map<std::string, immer::flex_vector<std::string>> devices;
205 ar & txnId & event & devices;
207 std::move(txnId), std::move(event), std::move(devices));
208 } else {
209 ar & e.txnId & e.messages;
210 }
211 }
212
223 auto sortKeyForTimelineEvent(Event e) -> std::tuple<Timestamp, std::string>;
224
236 {
238 using ReverseEventRelationshipMap = immer::map<
239 std::string /* related event id */,
240 immer::map<std::string /* relation type */, immer::flex_vector<std::string /* relater event id */>>>;
241
242 std::string roomId;
243 immer::map<KeyOfState, Event> stateEvents;
244 immer::map<KeyOfState, Event> inviteState;
245 // Smaller indices mean earlier events
246 // (oldest) 0 --------> n (latest)
247 immer::flex_vector<std::string> timeline;
248 immer::map<std::string, Event> messages;
249 immer::map<std::string, Event> accountData;
251 std::string paginateBackToken;
253 bool canPaginateBack{true};
254
255 immer::map<std::string /* eventId */, std::string /* prevBatch */> timelineGaps;
256
257 immer::map<std::string, Event> ephemeral;
258
259 std::string localDraft;
260
261 bool encrypted{false};
267
269 immer::flex_vector<std::string> heroIds;
270
271 immer::flex_vector<LocalEchoDesc> localEchoes;
272
273 immer::flex_vector<PendingRoomKeyEvent> pendingRoomKeyEvents;
274
276
277 std::size_t joinedMemberCount{0};
278 std::size_t invitedMemberCount{0};
279
282 std::string localReadMarker;
284 std::size_t localUnreadCount{0};
289 immer::map<std::string /* userId */, ReadReceipt> readReceipts;
292 immer::map<
293 std::string /* eventId */,
294 immer::flex_vector<std::string /* userId */>> eventReadUsers;
295
298 immer::map<
299 std::string /* sessionId */,
300 immer::flex_vector<std::string /* eventId */>> undecryptedEvents;
301
302 immer::flex_vector<std::string> unreadNotificationEventIds;
307 immer::set<std::string> nonTimelineEvents;
308
309 immer::flex_vector<std::string> joinedMemberIds() const;
310 immer::flex_vector<std::string> invitedMemberIds() const;
311 immer::flex_vector<std::string> knockedMemberIds() const;
312 immer::flex_vector<std::string> leftMemberIds() const;
313 immer::flex_vector<std::string> bannedMemberIds() const;
314
321
323
324 bool hasUser(std::string userId) const;
325
326 std::optional<LocalEchoDesc> getLocalEchoByTxnId(std::string txnId) const;
327 std::optional<PendingRoomKeyEvent> getPendingRoomKeyEventByTxnId(std::string txnId) const;
328
329 immer::map<std::string, double> tags() const;
330
331 Event makeAddTagEvent(std::string tagId, std::optional<double> order) const;
332 Event makeRemoveTagEvent(std::string tagId) const;
333
341 void generateRelationships(EventList newEvents);
342
344
351 void addToUndecryptedEvents(EventList newEvents);
352
354
359 bool checkInvariants() const;
360
368 bool isInTimeline(const std::string &eventId) const;
369
370 using Action = std::variant<
393 >;
394
395 static RoomModel update(RoomModel r, Action a);
396
397 friend bool operator==(const RoomModel &a, const RoomModel &b) = default;
398 };
399
401
403 {
404 std::string roomId;
406 };
407
409 {
410 immer::map<std::string, RoomModel> rooms;
411
412 inline auto at(std::string id) const { return rooms.at(id); }
413 inline auto operator[](std::string id) const { return rooms[id]; }
414 inline bool has(std::string id) const { return rooms.find(id); }
415
416 using Action = std::variant<
418 >;
420
421 friend bool operator==(const RoomListModel &a, const RoomListModel &b) = default;
422 };
423
425
426 template<class Archive>
427 void serialize(Archive &ar, RoomModel &r, std::uint32_t const version)
428 {
429 ar
430 & r.roomId
431 & r.stateEvents
432 & r.inviteState
433
434 & r.timeline
435 & r.messages
436 & r.accountData
437 & r.membership
440
441 & r.timelineGaps
442 & r.ephemeral
443
444 & r.localDraft
445
446 & r.encrypted
448
450 ;
451
452 if (version >= 1) {
453 ar
454 & r.heroIds
455 ;
456 }
457 if (version >= 2) {
458 ar & r.localEchoes;
459 }
460 if (version >= 3) {
462 }
463 if (version >= 4) {
465 } else { // must be reading from an older version
466 if constexpr (typename Archive::is_loading()) {
468 }
469 }
470 if (version >= 5) {
472 }
473 if (version >= 6) {
474 ar
478 & r.readReceipts
479 & r.eventReadUsers;
480 }
481 if (version >= 7) {
482 ar & r.undecryptedEvents;
483 } else {
484 if constexpr (typename Archive::is_loading()) {
486 }
487 }
488 if (version >= 8) {
490 }
491 if (version >= 9) {
492 ar & r.nonTimelineEvents;
493 }
494 }
495
496 template<class Archive>
497 void serialize(Archive &ar, RoomListModel &l, std::uint32_t const /*version*/)
498 {
499 ar & l.rooms;
500 }
501}
502
503BOOST_CLASS_VERSION(Kazv::PendingRoomKeyEvent, 1)
504BOOST_CLASS_VERSION(Kazv::ReadReceipt, 0)
505BOOST_CLASS_VERSION(Kazv::RoomModel, 9)
506BOOST_CLASS_VERSION(Kazv::RoomListModel, 0)
Definition event.hpp:21
Definition push-rules-desc.hpp:38
Definition location.hpp:10
RoomModel::Action RoomAction
Definition room-model.hpp:400
const double ROOM_TAG_DEFAULT_ORDER
Definition room-model.hpp:195
std::int_fast64_t Timestamp
Definition event.hpp:18
auto sortKeyForTimelineEvent(Event e) -> std::tuple< Timestamp, std::string >
Get the sort key for a timeline event.
Definition room-model.cpp:56
RoomMembership
Definition types.hpp:128
immer::flex_vector< Event > EventList
Definition types.hpp:107
PendingRoomKeyEvent makePendingRoomKeyEventV0(std::string txnId, Event event, immer::map< std::string, immer::flex_vector< std::string > > devices)
Definition room-model.cpp:40
void serialize(Archive &ar, ClientModel &m, std::uint32_t const version)
Definition client-model.hpp:633
RoomListModel::Action RoomListAction
Definition room-model.hpp:424
Definition room-model.hpp:99
immer::flex_vector< Event > events
Definition room-model.hpp:100
Definition room-model.hpp:114
EventList events
Definition room-model.hpp:115
Definition room-model.hpp:137
LocalEchoDesc localEcho
Definition room-model.hpp:138
Update local notifications to include the new events.
Definition room-model.hpp:170
std::string myUserId
Definition room-model.hpp:173
EventList newEvents
Definition room-model.hpp:171
PushRulesDesc pushRulesDesc
Definition room-model.hpp:172
Add events to the messages map, but not the timeline.
Definition room-model.hpp:83
bool alsoInTimeline
Definition room-model.hpp:86
EventList events
Definition room-model.hpp:84
Definition room-model.hpp:147
PendingRoomKeyEvent pendingRoomKeyEvent
Definition room-model.hpp:148
Definition room-model.hpp:68
immer::flex_vector< Event > stateEvents
Definition room-model.hpp:69
Definition room-model.hpp:90
std::optional< std::string > prevBatch
Definition room-model.hpp:93
std::optional< std::string > gapEventId
Definition room-model.hpp:95
std::optional< bool > limited
Definition room-model.hpp:94
immer::flex_vector< Event > events
Events from oldest to latest.
Definition room-model.hpp:92
Definition room-model.hpp:109
immer::flex_vector< Event > events
Definition room-model.hpp:110
Definition room-model.hpp:104
RoomMembership membership
Definition room-model.hpp:105
Definition room-model.hpp:60
friend bool operator!=(const EventReader &a, const EventReader &b)=default
friend bool operator==(const EventReader &a, const EventReader &b)=default
std::string userId
Definition room-model.hpp:61
Timestamp timestamp
Definition room-model.hpp:62
Describes a local echo.
Definition local-echo.hpp:19
Definition room-model.hpp:128
Go from the back of stateEvents to the beginning, adding the event to room state only if the room has...
Definition room-model.hpp:76
immer::flex_vector< Event > stateEvents
Definition room-model.hpp:77
Definition crypto.hpp:27
Definition room-model.hpp:34
friend bool operator!=(const PendingRoomKeyEvent &a, const PendingRoomKeyEvent &b)=default
immer::map< std::string, immer::map< std::string, Event > > messages
Definition room-model.hpp:36
friend bool operator==(const PendingRoomKeyEvent &a, const PendingRoomKeyEvent &b)=default
std::string txnId
Definition room-model.hpp:35
Remove events from the model, retaining only the latest maxToKeep events.
Definition room-model.hpp:191
std::size_t maxToKeep
Definition room-model.hpp:192
Definition room-model.hpp:45
Timestamp timestamp
Definition room-model.hpp:47
std::string eventId
Definition room-model.hpp:46
friend bool operator!=(const ReadReceipt &a, const ReadReceipt &b)=default
friend bool operator==(const ReadReceipt &a, const ReadReceipt &b)=default
Definition room-model.hpp:142
std::string txnId
Definition room-model.hpp:143
Definition room-model.hpp:152
std::string txnId
Definition room-model.hpp:153
Remove local notifications that are already read.
Definition room-model.hpp:178
std::string myUserId
Definition room-model.hpp:179
Definition room-model.hpp:409
std::variant< UpdateRoomAction > Action
Definition room-model.hpp:418
auto at(std::string id) const
Definition room-model.hpp:412
static RoomListModel update(RoomListModel l, Action a)
Definition room-model.cpp:451
bool has(std::string id) const
Definition room-model.hpp:414
immer::map< std::string, RoomModel > rooms
Definition room-model.hpp:410
friend bool operator==(const RoomListModel &a, const RoomListModel &b)=default
auto operator[](std::string id) const
Definition room-model.hpp:413
The model to store information about a room.
Definition room-model.hpp:236
immer::flex_vector< std::string > unreadNotificationEventIds
Definition room-model.hpp:302
immer::map< KeyOfState, Event > stateEvents
Definition room-model.hpp:243
EventList invitedMemberEvents() const
Definition room-model.cpp:539
EventList knockedMemberEvents() const
Definition room-model.cpp:544
Event makeRemoveTagEvent(std::string tagId) const
Definition room-model.cpp:679
bool canPaginateBack
whether this room has earlier events to be fetched
Definition room-model.hpp:253
immer::map< std::string, std::string > timelineGaps
Definition room-model.hpp:255
immer::map< std::string, Event > ephemeral
Definition room-model.hpp:257
bool encrypted
Definition room-model.hpp:261
immer::map< std::string, double > tags() const
Definition room-model.cpp:638
immer::flex_vector< std::string > timeline
Definition room-model.hpp:247
std::string paginateBackToken
Definition room-model.hpp:251
immer::map< std::string, immer::map< std::string, immer::flex_vector< std::string > > > ReverseEventRelationshipMap
Definition room-model.hpp:240
immer::set< std::string > nonTimelineEvents
The set of event ids that are in messages but not in timeline.
Definition room-model.hpp:307
Event makeAddTagEvent(std::string tagId, std::optional< double > order) const
Definition room-model.cpp:667
MegOlmSessionRotateDesc sessionRotateDesc() const
Definition room-model.cpp:579
EventList heroMemberEvents() const
Definition room-model.cpp:559
void regenerateRelationships()
Definition room-model.cpp:698
EventList bannedMemberEvents() const
Definition room-model.cpp:554
immer::map< std::string, Event > messages
Definition room-model.hpp:248
void generateRelationships(EventList newEvents)
Fill in reverseEventRelationships by gathering the relationships specified in newEvents
Definition room-model.cpp:686
std::size_t localNotificationCount
The local unread notification count for this room.
Definition room-model.hpp:287
std::size_t joinedMemberCount
Definition room-model.hpp:277
void addToUndecryptedEvents(EventList newEvents)
Fill in undecryptedEvents by gathering the session ids specified in newEvents.
Definition room-model.cpp:705
std::size_t localUnreadCount
The local unread count for this room.
Definition room-model.hpp:284
std::string localDraft
Definition room-model.hpp:259
immer::flex_vector< std::string > knockedMemberIds() const
Definition room-model.cpp:519
bool isInTimeline(const std::string &eventId) const
Check if the event is in the timeline.
Definition room-model.cpp:760
bool checkInvariants() const
Check if the invariants in the model are satisfied.
Definition room-model.cpp:740
immer::map< std::string, immer::flex_vector< std::string > > eventReadUsers
A map from event id to a list of users that has read receipt at that point.
Definition room-model.hpp:294
EventList leftMemberEvents() const
Definition room-model.cpp:549
immer::flex_vector< std::string > heroIds
Definition room-model.hpp:269
std::optional< PendingRoomKeyEvent > getPendingRoomKeyEventByTxnId(std::string txnId) const
Definition room-model.cpp:617
immer::flex_vector< LocalEchoDesc > localEchoes
Definition room-model.hpp:271
std::optional< LocalEchoDesc > getLocalEchoByTxnId(std::string txnId) const
Definition room-model.cpp:605
std::string roomId
Definition room-model.hpp:242
EventList joinedMemberEvents() const
Definition room-model.cpp:534
bool membersFullyLoaded
Definition room-model.hpp:268
std::variant< AddStateEventsAction, MaybeAddStateEventsAction, AddMessagesAction, AddToTimelineAction, AddAccountDataAction, ChangeMembershipAction, ChangeInviteStateAction, AddEphemeralAction, SetLocalDraftAction, SetRoomEncryptionAction, MarkMembersFullyLoadedAction, SetHeroIdsAction, AddLocalEchoAction, RemoveLocalEchoAction, AddPendingRoomKeyAction, RemovePendingRoomKeyAction, UpdateJoinedMemberCountAction, UpdateInvitedMemberCountAction, AddLocalNotificationsAction, RemoveReadLocalNotificationsAction, UpdateLocalReadMarkerAction, PurgeEventsAction > Action
Definition room-model.hpp:393
std::size_t invitedMemberCount
Definition room-model.hpp:278
immer::flex_vector< std::string > invitedMemberIds() const
Definition room-model.cpp:514
ReverseEventRelationshipMap reverseEventRelationships
Definition room-model.hpp:275
bool hasUser(std::string userId) const
Definition room-model.cpp:592
immer::map< std::string, immer::flex_vector< std::string > > undecryptedEvents
A map from the session id to a list of event ids of events that cannot (yet) be decrypted.
Definition room-model.hpp:300
immer::flex_vector< std::string > bannedMemberIds() const
Definition room-model.cpp:529
immer::flex_vector< PendingRoomKeyEvent > pendingRoomKeyEvents
Definition room-model.hpp:273
friend bool operator==(const RoomModel &a, const RoomModel &b)=default
immer::map< std::string, Event > accountData
Definition room-model.hpp:249
void recalculateUndecryptedEvents()
Definition room-model.cpp:729
immer::map< std::string, ReadReceipt > readReceipts
Read receipts for all users.
Definition room-model.hpp:289
bool shouldRotateSessionKey
a marker to indicate whether we need to rotate the session key earlier than it expires (e....
Definition room-model.hpp:266
immer::flex_vector< std::string > joinedMemberIds() const
Definition room-model.cpp:509
Membership membership
Definition room-model.hpp:250
std::string localReadMarker
The local read marker for this room.
Definition room-model.hpp:282
immer::map< KeyOfState, Event > inviteState
Definition room-model.hpp:244
immer::flex_vector< std::string > leftMemberIds() const
Definition room-model.cpp:524
static RoomModel update(RoomModel r, Action a)
Definition room-model.cpp:61
Definition room-model.hpp:132
immer::flex_vector< std::string > heroIds
Definition room-model.hpp:133
Definition room-model.hpp:119
std::string localDraft
Definition room-model.hpp:120
Definition room-model.hpp:124
Definition room-model.hpp:162
std::size_t invitedMemberCount
Definition room-model.hpp:163
Definition room-model.hpp:157
std::size_t joinedMemberCount
Definition room-model.hpp:158
Update the local read marker, removing any read notifications before it.
Definition room-model.hpp:184
std::string myUserId
Definition room-model.hpp:186
std::string localReadMarker
Definition room-model.hpp:185
Definition room-model.hpp:403
RoomAction roomAction
Definition room-model.hpp:405
std::string roomId
Definition room-model.hpp:404