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
378 bool isReadBy(const std::string &eventId, const std::string &userId) const;
379
380 using Action = std::variant<
403 >;
404
405 static RoomModel update(RoomModel r, Action a);
406
407 friend bool operator==(const RoomModel &a, const RoomModel &b) = default;
408 };
409
411
413 {
414 std::string roomId;
416 };
417
419 {
420 immer::map<std::string, RoomModel> rooms;
421
422 inline auto at(std::string id) const { return rooms.at(id); }
423 inline auto operator[](std::string id) const { return rooms[id]; }
424 inline bool has(std::string id) const { return rooms.find(id); }
425
426 using Action = std::variant<
428 >;
430
431 friend bool operator==(const RoomListModel &a, const RoomListModel &b) = default;
432 };
433
435
436 template<class Archive>
437 void serialize(Archive &ar, RoomModel &r, std::uint32_t const version)
438 {
439 ar
440 & r.roomId
441 & r.stateEvents
442 & r.inviteState
443
444 & r.timeline
445 & r.messages
446 & r.accountData
447 & r.membership
450
451 & r.timelineGaps
452 & r.ephemeral
453
454 & r.localDraft
455
456 & r.encrypted
458
460 ;
461
462 if (version >= 1) {
463 ar
464 & r.heroIds
465 ;
466 }
467 if (version >= 2) {
468 ar & r.localEchoes;
469 }
470 if (version >= 3) {
472 }
473 if (version >= 4) {
475 } else { // must be reading from an older version
476 if constexpr (typename Archive::is_loading()) {
478 }
479 }
480 if (version >= 5) {
482 }
483 if (version >= 6) {
484 ar
488 & r.readReceipts
489 & r.eventReadUsers;
490 }
491 if (version >= 7) {
492 ar & r.undecryptedEvents;
493 } else {
494 if constexpr (typename Archive::is_loading()) {
496 }
497 }
498 if (version >= 8) {
500 }
501 if (version >= 9) {
502 ar & r.nonTimelineEvents;
503 }
504 }
505
506 template<class Archive>
507 void serialize(Archive &ar, RoomListModel &l, std::uint32_t const /*version*/)
508 {
509 ar & l.rooms;
510 }
511}
512
513BOOST_CLASS_VERSION(Kazv::PendingRoomKeyEvent, 1)
514BOOST_CLASS_VERSION(Kazv::ReadReceipt, 0)
515BOOST_CLASS_VERSION(Kazv::RoomModel, 9)
516BOOST_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:410
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:694
RoomListModel::Action RoomListAction
Definition room-model.hpp:434
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:419
std::variant< UpdateRoomAction > Action
Definition room-model.hpp:428
auto at(std::string id) const
Definition room-model.hpp:422
static RoomListModel update(RoomListModel l, Action a)
Definition room-model.cpp:451
bool has(std::string id) const
Definition room-model.hpp:424
immer::map< std::string, RoomModel > rooms
Definition room-model.hpp:420
friend bool operator==(const RoomListModel &a, const RoomListModel &b)=default
auto operator[](std::string id) const
Definition room-model.hpp:423
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
bool isReadBy(const std::string &eventId, const std::string &userId) const
Check if an event has been read by the given user.
Definition room-model.cpp:765
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:403
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:413
RoomAction roomAction
Definition room-model.hpp:415
std::string roomId
Definition room-model.hpp:414