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#include "local-draft.hpp"
31
32namespace Kazv
33{
35 {
36 std::string txnId;
37 immer::map<std::string, immer::map<std::string, Event>> messages;
38
39 friend bool operator==(const PendingRoomKeyEvent &a, const PendingRoomKeyEvent &b) = default;
40 friend bool operator!=(const PendingRoomKeyEvent &a, const PendingRoomKeyEvent &b) = default;
41 };
42
43 PendingRoomKeyEvent makePendingRoomKeyEventV0(std::string txnId, Event event, immer::map<std::string, immer::flex_vector<std::string>> devices);
44
46 {
47 std::string eventId;
49 friend bool operator==(const ReadReceipt &a, const ReadReceipt &b) = default;
50 friend bool operator!=(const ReadReceipt &a, const ReadReceipt &b) = default;
51 };
52
53 template<class Archive>
54 void serialize(Archive &ar, ReadReceipt &r, std::uint32_t const /* version */)
55 {
56 ar & r.eventId & r.timestamp;
57 }
58
59
61 {
62 std::string userId;
64 friend bool operator==(const EventReader &a, const EventReader &b) = default;
65 friend bool operator!=(const EventReader &a, const EventReader &b) = default;
66 };
67
69 {
70 immer::flex_vector<Event> stateEvents;
71 };
72
77 {
78 immer::flex_vector<Event> stateEvents;
79 };
80
84 {
87 bool alsoInTimeline{false};
88 };
89
91 {
93 immer::flex_vector<Event> events;
94 std::optional<std::string> prevBatch;
95 std::optional<bool> limited;
96 std::optional<std::string> gapEventId;
97 };
98
100 {
101 immer::flex_vector<Event> events;
102 };
103
108
110 {
111 immer::flex_vector<Event> events;
112 };
113
118
120 {
121 std::string localDraft;
122 };
123
125 {
126 std::string relType;
127 std::string relatedEventId;
128 };
129
131 {
132 std::string text;
133 std::string relType;
134 std::string relatedEventId;
135 };
136
138 {
139 std::string text;
140 std::string relType;
141 std::string relatedEventId;
142 };
143
145 {
146 };
147
149 {
150 };
151
153 {
154 };
155
157 {
158 immer::flex_vector<std::string> heroIds;
159 };
160
165
167 {
168 std::string txnId;
169 };
170
175
177 {
178 std::string txnId;
179 };
180
182 {
183 std::size_t joinedMemberCount;
184 };
185
190
200
203 {
204 std::string myUserId;
205 };
206
209 {
210 std::string localReadMarker;
211 std::string myUserId;
212 };
213
216 {
217 std::size_t maxToKeep;
218 };
219
220 inline const double ROOM_TAG_DEFAULT_ORDER = 2;
221
222 template<class Archive>
223 void serialize(Archive &ar, PendingRoomKeyEvent &e, std::uint32_t const version)
224 {
225 if (version < 1) {
226 // loading an older version where there is only one event
227 std::string txnId;
228 Event event;
229 immer::map<std::string, immer::flex_vector<std::string>> devices;
230 ar & txnId & event & devices;
232 std::move(txnId), std::move(event), std::move(devices));
233 } else {
234 ar & e.txnId & e.messages;
235 }
236 }
237
248 auto sortKeyForTimelineEvent(Event e) -> std::tuple<Timestamp, std::string>;
249
261 {
263 using ReverseEventRelationshipMap = immer::map<
264 std::string /* related event id */,
265 immer::map<std::string /* relation type */, immer::flex_vector<std::string /* relater event id */>>>;
266
267 std::string roomId;
268 immer::map<KeyOfState, Event> stateEvents;
269 immer::map<KeyOfState, Event> inviteState;
270 // Smaller indices mean earlier events
271 // (oldest) 0 --------> n (latest)
272 immer::flex_vector<std::string> timeline;
273 immer::map<std::string, Event> messages;
274 immer::map<std::string, Event> accountData;
276 std::string paginateBackToken;
278 bool canPaginateBack{true};
279
280 immer::map<std::string /* eventId */, std::string /* prevBatch */> timelineGaps;
281
282 immer::map<std::string, Event> ephemeral;
283
284 immer::flex_vector<LocalDraft> localDrafts{
285 Kazv::LocalDraft{"", "", ""}
286 };
287
288 bool encrypted{false};
294
296 immer::flex_vector<std::string> heroIds;
297
298 immer::flex_vector<LocalEchoDesc> localEchoes;
299
300 immer::flex_vector<PendingRoomKeyEvent> pendingRoomKeyEvents;
301
303
304 std::size_t joinedMemberCount{0};
305 std::size_t invitedMemberCount{0};
306
309 std::string localReadMarker;
311 std::size_t localUnreadCount{0};
316 immer::map<std::string /* userId */, ReadReceipt> readReceipts;
319 immer::map<
320 std::string /* eventId */,
321 immer::flex_vector<std::string /* userId */>> eventReadUsers;
322
325 immer::map<
326 std::string /* sessionId */,
327 immer::flex_vector<std::string /* eventId */>> undecryptedEvents;
328
329 immer::flex_vector<std::string> unreadNotificationEventIds;
334 immer::set<std::string> nonTimelineEvents;
335
336 immer::flex_vector<std::string> joinedMemberIds() const;
337 immer::flex_vector<std::string> invitedMemberIds() const;
338 immer::flex_vector<std::string> knockedMemberIds() const;
339 immer::flex_vector<std::string> leftMemberIds() const;
340 immer::flex_vector<std::string> bannedMemberIds() const;
341
348
350
351 bool hasUser(std::string userId) const;
352
353 std::optional<LocalEchoDesc> getLocalEchoByTxnId(std::string txnId) const;
354 std::optional<PendingRoomKeyEvent> getPendingRoomKeyEventByTxnId(std::string txnId) const;
355
356 immer::map<std::string, double> tags() const;
357
358 Event makeAddTagEvent(std::string tagId, std::optional<double> order) const;
359 Event makeRemoveTagEvent(std::string tagId) const;
360
368 void generateRelationships(EventList newEvents);
369
371
378 void addToUndecryptedEvents(EventList newEvents);
379
381
386 bool checkInvariants() const;
387
395 bool isInTimeline(const std::string &eventId) const;
396
397
405 bool isReadBy(const std::string &eventId, const std::string &userId) const;
406
407 using Action = std::variant<
434 >;
435
436 static RoomModel update(RoomModel r, Action a);
437
438 friend bool operator==(const RoomModel &a, const RoomModel &b) = default;
439 };
440
442
444 {
445 std::string roomId;
447 };
448
450 {
451 immer::map<std::string, RoomModel> rooms;
452
453 inline auto at(std::string id) const { return rooms.at(id); }
454 inline auto operator[](std::string id) const { return rooms[id]; }
455 inline bool has(std::string id) const { return rooms.find(id); }
456
457 using Action = std::variant<
459 >;
461
462 friend bool operator==(const RoomListModel &a, const RoomListModel &b) = default;
463 };
464
466
467 template<class Archive>
468 void serialize(Archive &ar, RoomModel &r, std::uint32_t const version)
469 {
470 ar
471 & r.roomId
472 & r.stateEvents
473 & r.inviteState
474
475 & r.timeline
476 & r.messages
477 & r.accountData
478 & r.membership
481
482 & r.timelineGaps
483 & r.ephemeral
484 ;
485 if (version < 10) {
486 std::string oldVerLocalDraft;
487 ar & oldVerLocalDraft;
488 r.localDrafts = {LocalDraft{oldVerLocalDraft, "", ""}};
489 }
490 ar
491 & r.encrypted
493
495 ;
496
497 if (version >= 1) {
498 ar
499 & r.heroIds
500 ;
501 }
502 if (version >= 2) {
503 ar & r.localEchoes;
504 }
505 if (version >= 3) {
507 }
508 if (version >= 4) {
510 } else { // must be reading from an older version
511 if constexpr (typename Archive::is_loading()) {
513 }
514 }
515 if (version >= 5) {
517 }
518 if (version >= 6) {
519 ar
523 & r.readReceipts
524 & r.eventReadUsers;
525 }
526 if (version >= 7) {
527 ar & r.undecryptedEvents;
528 } else {
529 if constexpr (typename Archive::is_loading()) {
531 }
532 }
533 if (version >= 8) {
535 }
536 if (version >= 9) {
537 ar & r.nonTimelineEvents;
538 }
539 if (version >= 10) {
540 ar & r.localDrafts;
541 }
542 }
543
544 template<class Archive>
545 void serialize(Archive &ar, RoomListModel &l, std::uint32_t const /*version*/)
546 {
547 ar & l.rooms;
548 }
549}
550
551BOOST_CLASS_VERSION(Kazv::PendingRoomKeyEvent, 1)
552BOOST_CLASS_VERSION(Kazv::ReadReceipt, 0)
553BOOST_CLASS_VERSION(Kazv::RoomModel, 10)
554BOOST_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:441
const double ROOM_TAG_DEFAULT_ORDER
Definition room-model.hpp:220
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:465
Definition room-model.hpp:100
immer::flex_vector< Event > events
Definition room-model.hpp:101
Definition room-model.hpp:115
EventList events
Definition room-model.hpp:116
Definition room-model.hpp:162
LocalEchoDesc localEcho
Definition room-model.hpp:163
Update local notifications to include the new events.
Definition room-model.hpp:195
std::string myUserId
Definition room-model.hpp:198
EventList newEvents
Definition room-model.hpp:196
PushRulesDesc pushRulesDesc
Definition room-model.hpp:197
Add events to the messages map, but not the timeline.
Definition room-model.hpp:84
bool alsoInTimeline
Definition room-model.hpp:87
EventList events
Definition room-model.hpp:85
Definition room-model.hpp:172
PendingRoomKeyEvent pendingRoomKeyEvent
Definition room-model.hpp:173
Definition room-model.hpp:69
immer::flex_vector< Event > stateEvents
Definition room-model.hpp:70
Definition room-model.hpp:91
std::optional< std::string > prevBatch
Definition room-model.hpp:94
std::optional< std::string > gapEventId
Definition room-model.hpp:96
std::optional< bool > limited
Definition room-model.hpp:95
immer::flex_vector< Event > events
Events from oldest to latest.
Definition room-model.hpp:93
Definition room-model.hpp:110
immer::flex_vector< Event > events
Definition room-model.hpp:111
Definition room-model.hpp:105
RoomMembership membership
Definition room-model.hpp:106
Definition room-model.hpp:61
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:62
Timestamp timestamp
Definition room-model.hpp:63
Local draft.
Definition local-draft.hpp:22
Describes a local echo.
Definition local-echo.hpp:19
Definition room-model.hpp:153
Go from the back of stateEvents to the beginning, adding the event to room state only if the room has...
Definition room-model.hpp:77
immer::flex_vector< Event > stateEvents
Definition room-model.hpp:78
Definition crypto.hpp:27
Definition room-model.hpp:35
friend bool operator!=(const PendingRoomKeyEvent &a, const PendingRoomKeyEvent &b)=default
immer::map< std::string, immer::map< std::string, Event > > messages
Definition room-model.hpp:37
friend bool operator==(const PendingRoomKeyEvent &a, const PendingRoomKeyEvent &b)=default
std::string txnId
Definition room-model.hpp:36
Definition room-model.hpp:145
Remove events from the model, retaining only the latest maxToKeep events.
Definition room-model.hpp:216
std::size_t maxToKeep
Definition room-model.hpp:217
Definition room-model.hpp:138
std::string text
Definition room-model.hpp:139
std::string relType
Definition room-model.hpp:140
std::string relatedEventId
Definition room-model.hpp:141
Definition room-model.hpp:46
Timestamp timestamp
Definition room-model.hpp:48
std::string eventId
Definition room-model.hpp:47
friend bool operator!=(const ReadReceipt &a, const ReadReceipt &b)=default
friend bool operator==(const ReadReceipt &a, const ReadReceipt &b)=default
Definition room-model.hpp:167
std::string txnId
Definition room-model.hpp:168
Definition room-model.hpp:177
std::string txnId
Definition room-model.hpp:178
Remove local notifications that are already read.
Definition room-model.hpp:203
std::string myUserId
Definition room-model.hpp:204
Definition room-model.hpp:450
std::variant< UpdateRoomAction > Action
Definition room-model.hpp:459
auto at(std::string id) const
Definition room-model.hpp:453
static RoomListModel update(RoomListModel l, Action a)
Definition room-model.cpp:498
bool has(std::string id) const
Definition room-model.hpp:455
immer::map< std::string, RoomModel > rooms
Definition room-model.hpp:451
friend bool operator==(const RoomListModel &a, const RoomListModel &b)=default
auto operator[](std::string id) const
Definition room-model.hpp:454
The model to store information about a room.
Definition room-model.hpp:261
immer::flex_vector< std::string > unreadNotificationEventIds
Definition room-model.hpp:329
immer::map< KeyOfState, Event > stateEvents
Definition room-model.hpp:268
EventList invitedMemberEvents() const
Definition room-model.cpp:586
EventList knockedMemberEvents() const
Definition room-model.cpp:591
Event makeRemoveTagEvent(std::string tagId) const
Definition room-model.cpp:726
bool canPaginateBack
whether this room has earlier events to be fetched
Definition room-model.hpp:278
immer::map< std::string, std::string > timelineGaps
Definition room-model.hpp:280
immer::map< std::string, Event > ephemeral
Definition room-model.hpp:282
bool encrypted
Definition room-model.hpp:288
immer::map< std::string, double > tags() const
Definition room-model.cpp:685
immer::flex_vector< std::string > timeline
Definition room-model.hpp:272
std::string paginateBackToken
Definition room-model.hpp:276
immer::map< std::string, immer::map< std::string, immer::flex_vector< std::string > > > ReverseEventRelationshipMap
Definition room-model.hpp:265
immer::set< std::string > nonTimelineEvents
The set of event ids that are in messages but not in timeline.
Definition room-model.hpp:334
Event makeAddTagEvent(std::string tagId, std::optional< double > order) const
Definition room-model.cpp:714
MegOlmSessionRotateDesc sessionRotateDesc() const
Definition room-model.cpp:626
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:812
EventList heroMemberEvents() const
Definition room-model.cpp:606
void regenerateRelationships()
Definition room-model.cpp:745
EventList bannedMemberEvents() const
Definition room-model.cpp:601
immer::map< std::string, Event > messages
Definition room-model.hpp:273
void generateRelationships(EventList newEvents)
Fill in reverseEventRelationships by gathering the relationships specified in newEvents
Definition room-model.cpp:733
std::size_t localNotificationCount
The local unread notification count for this room.
Definition room-model.hpp:314
std::size_t joinedMemberCount
Definition room-model.hpp:304
void addToUndecryptedEvents(EventList newEvents)
Fill in undecryptedEvents by gathering the session ids specified in newEvents.
Definition room-model.cpp:752
std::size_t localUnreadCount
The local unread count for this room.
Definition room-model.hpp:311
immer::flex_vector< std::string > knockedMemberIds() const
Definition room-model.cpp:566
bool isInTimeline(const std::string &eventId) const
Check if the event is in the timeline.
Definition room-model.cpp:807
bool checkInvariants() const
Check if the invariants in the model are satisfied.
Definition room-model.cpp:787
std::variant< AddStateEventsAction, MaybeAddStateEventsAction, AddMessagesAction, AddToTimelineAction, AddAccountDataAction, ChangeMembershipAction, ChangeInviteStateAction, AddEphemeralAction, SetLocalDraftTextAction, SetLocalDraftRelAction, SetLocalDraftAction, PushLocalDraftAction, PopLocalDraftAction, SetRoomEncryptionAction, MarkMembersFullyLoadedAction, SetHeroIdsAction, AddLocalEchoAction, RemoveLocalEchoAction, AddPendingRoomKeyAction, RemovePendingRoomKeyAction, UpdateJoinedMemberCountAction, UpdateInvitedMemberCountAction, AddLocalNotificationsAction, RemoveReadLocalNotificationsAction, UpdateLocalReadMarkerAction, PurgeEventsAction > Action
Definition room-model.hpp:434
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:321
EventList leftMemberEvents() const
Definition room-model.cpp:596
immer::flex_vector< std::string > heroIds
Definition room-model.hpp:296
std::optional< PendingRoomKeyEvent > getPendingRoomKeyEventByTxnId(std::string txnId) const
Definition room-model.cpp:664
immer::flex_vector< LocalEchoDesc > localEchoes
Definition room-model.hpp:298
std::optional< LocalEchoDesc > getLocalEchoByTxnId(std::string txnId) const
Definition room-model.cpp:652
std::string roomId
Definition room-model.hpp:267
EventList joinedMemberEvents() const
Definition room-model.cpp:581
bool membersFullyLoaded
Definition room-model.hpp:295
std::size_t invitedMemberCount
Definition room-model.hpp:305
immer::flex_vector< std::string > invitedMemberIds() const
Definition room-model.cpp:561
ReverseEventRelationshipMap reverseEventRelationships
Definition room-model.hpp:302
bool hasUser(std::string userId) const
Definition room-model.cpp:639
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:327
immer::flex_vector< std::string > bannedMemberIds() const
Definition room-model.cpp:576
immer::flex_vector< PendingRoomKeyEvent > pendingRoomKeyEvents
Definition room-model.hpp:300
friend bool operator==(const RoomModel &a, const RoomModel &b)=default
immer::map< std::string, Event > accountData
Definition room-model.hpp:274
void recalculateUndecryptedEvents()
Definition room-model.cpp:776
immer::map< std::string, ReadReceipt > readReceipts
Read receipts for all users.
Definition room-model.hpp:316
bool shouldRotateSessionKey
a marker to indicate whether we need to rotate the session key earlier than it expires (e....
Definition room-model.hpp:293
immer::flex_vector< std::string > joinedMemberIds() const
Definition room-model.cpp:556
Membership membership
Definition room-model.hpp:275
immer::flex_vector< LocalDraft > localDrafts
Definition room-model.hpp:284
std::string localReadMarker
The local read marker for this room.
Definition room-model.hpp:309
immer::map< KeyOfState, Event > inviteState
Definition room-model.hpp:269
immer::flex_vector< std::string > leftMemberIds() const
Definition room-model.cpp:571
static RoomModel update(RoomModel r, Action a)
Definition room-model.cpp:61
Definition room-model.hpp:157
immer::flex_vector< std::string > heroIds
Definition room-model.hpp:158
Definition room-model.hpp:131
std::string relatedEventId
Definition room-model.hpp:134
std::string text
Definition room-model.hpp:132
std::string relType
Definition room-model.hpp:133
Definition room-model.hpp:125
std::string relType
Definition room-model.hpp:126
std::string relatedEventId
Definition room-model.hpp:127
Definition room-model.hpp:120
std::string localDraft
Definition room-model.hpp:121
Definition room-model.hpp:149
Definition room-model.hpp:187
std::size_t invitedMemberCount
Definition room-model.hpp:188
Definition room-model.hpp:182
std::size_t joinedMemberCount
Definition room-model.hpp:183
Update the local read marker, removing any read notifications before it.
Definition room-model.hpp:209
std::string myUserId
Definition room-model.hpp:211
std::string localReadMarker
Definition room-model.hpp:210
Definition room-model.hpp:444
RoomAction roomAction
Definition room-model.hpp:446
std::string roomId
Definition room-model.hpp:445