libkazv
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 
20 
21 #include <csapi/sync.hpp>
22 #include <event.hpp>
23 
24 #include <crypto.hpp>
25 
26 #include "local-echo.hpp"
27 #include "clientutil.hpp"
28 
29 namespace Kazv
30 {
32  {
33  std::string txnId;
35  immer::map<std::string, immer::flex_vector<std::string>> devices;
36  };
37 
39  {
40  immer::flex_vector<Event> stateEvents;
41  };
42 
44  {
45  immer::flex_vector<Event> events;
46  };
47 
49  {
50  immer::flex_vector<Event> events;
51  std::string paginateBackToken;
52  };
53 
55  {
57  immer::flex_vector<Event> events;
58  std::optional<std::string> prevBatch;
59  std::optional<bool> limited;
60  std::optional<std::string> gapEventId;
61  };
62 
64  {
65  immer::flex_vector<Event> events;
66  };
67 
69  {
71  };
72 
74  {
75  immer::flex_vector<Event> events;
76  };
77 
79  {
81  };
82 
84  {
85  std::string localDraft;
86  };
87 
89  {
90  };
91 
93  {
94  };
95 
97  {
98  immer::flex_vector<std::string> heroIds;
99  };
100 
102  {
104  };
105 
107  {
108  std::string txnId;
109  };
110 
112  {
114  };
115 
117  {
118  std::string txnId;
119  };
120 
122  {
123  std::size_t joinedMemberCount;
124  };
125 
127  {
128  std::size_t invitedMemberCount;
129  };
130 
131  inline bool operator==(const PendingRoomKeyEvent &a, const PendingRoomKeyEvent &b)
132  {
133  return a.txnId == b.txnId && a.event == b.event && a.devices == b.devices;
134  }
135 
136  inline bool operator!=(const PendingRoomKeyEvent &a, const PendingRoomKeyEvent &b)
137  {
138  return !(a == b);
139  }
140 
141  inline const double ROOM_TAG_DEFAULT_ORDER = 2;
142 
143  template<class Archive>
144  void serialize(Archive &ar, PendingRoomKeyEvent &e, std::uint32_t const version)
145  {
146  ar & e.txnId & e.event & e.devices;
147  }
148 
149  struct RoomModel
150  {
152  using ReverseEventRelationshipMap = immer::map<
153  std::string /* related event id */,
154  immer::map<std::string /* relation type */, immer::flex_vector<std::string /* relater event id */>>>;
155 
156  std::string roomId;
157  immer::map<KeyOfState, Event> stateEvents;
158  immer::map<KeyOfState, Event> inviteState;
159  // Smaller indices mean earlier events
160  // (oldest) 0 --------> n (latest)
161  immer::flex_vector<std::string> timeline;
162  immer::map<std::string, Event> messages;
163  immer::map<std::string, Event> accountData;
165  std::string paginateBackToken;
167  bool canPaginateBack{true};
168 
169  immer::map<std::string /* eventId */, std::string /* prevBatch */> timelineGaps;
170 
171  immer::map<std::string, Event> ephemeral;
172 
173  std::string localDraft;
174 
175  bool encrypted{false};
181 
182  bool membersFullyLoaded{false};
183  immer::flex_vector<std::string> heroIds;
184 
185  immer::flex_vector<LocalEchoDesc> localEchoes;
186 
187  immer::flex_vector<PendingRoomKeyEvent> pendingRoomKeyEvents;
188 
190 
191  std::size_t joinedMemberCount{0};
192  std::size_t invitedMemberCount{0};
193 
194  immer::flex_vector<std::string> joinedMemberIds() const;
195  immer::flex_vector<std::string> invitedMemberIds() const;
196  immer::flex_vector<std::string> knockedMemberIds() const;
197  immer::flex_vector<std::string> leftMemberIds() const;
198  immer::flex_vector<std::string> bannedMemberIds() const;
199 
203  EventList leftMemberEvents() const;
205 
207 
208  bool hasUser(std::string userId) const;
209 
210  std::optional<LocalEchoDesc> getLocalEchoByTxnId(std::string txnId) const;
211  std::optional<PendingRoomKeyEvent> getPendingRoomKeyEventByTxnId(std::string txnId) const;
212 
213  immer::map<std::string, double> tags() const;
214 
215  Event makeAddTagEvent(std::string tagId, std::optional<double> order) const;
216  Event makeRemoveTagEvent(std::string tagId) const;
217 
225  void generateRelationships(EventList newEvents);
226 
228 
229  using Action = std::variant<
248  >;
249 
250  static RoomModel update(RoomModel r, Action a);
251  };
252 
254 
255  inline bool operator==(const RoomModel &a, const RoomModel &b)
256  {
257  return a.roomId == b.roomId
258  && a.stateEvents == b.stateEvents
259  && a.inviteState == b.inviteState
260  && a.timeline == b.timeline
261  && a.messages == b.messages
262  && a.accountData == b.accountData
263  && a.membership == b.membership
266  && a.timelineGaps == b.timelineGaps
267  && a.ephemeral == b.ephemeral
268  && a.localDraft == b.localDraft
269  && a.encrypted == b.encrypted
272  && a.heroIds == b.heroIds
273  && a.localEchoes == b.localEchoes
276  }
277 
279  {
280  std::string roomId;
282  };
283 
285  {
286  immer::map<std::string, RoomModel> rooms;
287 
288  inline auto at(std::string id) const { return rooms.at(id); }
289  inline auto operator[](std::string id) const { return rooms[id]; }
290  inline bool has(std::string id) const { return rooms.find(id); }
291 
292  using Action = std::variant<
294  >;
296  };
297 
299 
300  inline bool operator==(const RoomListModel &a, const RoomListModel &b)
301  {
302  return a.rooms == b.rooms;
303  }
304 
305  template<class Archive>
306  void serialize(Archive &ar, RoomModel &r, std::uint32_t const version)
307  {
308  ar
309  & r.roomId
310  & r.stateEvents
311  & r.inviteState
312 
313  & r.timeline
314  & r.messages
315  & r.accountData
316  & r.membership
318  & r.canPaginateBack
319 
320  & r.timelineGaps
321  & r.ephemeral
322 
323  & r.localDraft
324 
325  & r.encrypted
327 
329  ;
330 
331  if (version >= 1) {
332  ar
333  & r.heroIds
334  ;
335  }
336  if (version >= 2) {
337  ar & r.localEchoes;
338  }
339  if (version >= 3) {
340  ar & r.pendingRoomKeyEvents;
341  }
342  if (version >= 4) {
344  } else { // must be reading from an older version
345  if constexpr (typename Archive::is_loading()) {
347  }
348  }
349  if (version >= 5) {
351  }
352  }
353 
354  template<class Archive>
355  void serialize(Archive &ar, RoomListModel &l, std::uint32_t const /*version*/)
356  {
357  ar & l.rooms;
358  }
359 }
360 
361 BOOST_CLASS_VERSION(Kazv::PendingRoomKeyEvent, 0)
362 BOOST_CLASS_VERSION(Kazv::RoomModel, 5)
363 BOOST_CLASS_VERSION(Kazv::RoomListModel, 0)
Kazv::ChangeInviteStateAction::events
immer::flex_vector< Event > events
Definition: room-model.hpp:75
Kazv::RoomModel::tags
immer::map< std::string, double > tags() const
Definition: room-model.cpp:396
Kazv::AddLocalEchoAction
Definition: room-model.hpp:101
Kazv::PrependTimelineAction::events
immer::flex_vector< Event > events
Definition: room-model.hpp:50
Kazv::RoomModel::shouldRotateSessionKey
bool shouldRotateSessionKey
a marker to indicate whether we need to rotate the session key earlier than it expires (e....
Definition: room-model.hpp:180
immer-box.hpp
Kazv::AddToTimelineAction::gapEventId
std::optional< std::string > gapEventId
Definition: room-model.hpp:60
Kazv::RoomModel::invitedMemberEvents
EventList invitedMemberEvents() const
Definition: room-model.cpp:314
Kazv::RoomModel::heroIds
immer::flex_vector< std::string > heroIds
Definition: room-model.hpp:183
Kazv::RoomModel::membership
Membership membership
Definition: room-model.hpp:164
Kazv::RoomModel::messages
immer::map< std::string, Event > messages
Definition: room-model.hpp:162
Kazv::RoomModel::reverseEventRelationships
ReverseEventRelationshipMap reverseEventRelationships
Definition: room-model.hpp:189
Kazv::RoomListModel::update
static RoomListModel update(RoomListModel l, Action a)
Definition: room-model.cpp:226
Kazv::ChangeMembershipAction
Definition: room-model.hpp:68
Kazv::RoomModel::invitedMemberCount
std::size_t invitedMemberCount
Definition: room-model.hpp:192
Kazv::RoomModel::localDraft
std::string localDraft
Definition: room-model.hpp:173
Kazv::RoomModel::stateEvents
immer::map< KeyOfState, Event > stateEvents
Definition: room-model.hpp:157
Kazv::PendingRoomKeyEvent
Definition: room-model.hpp:31
Kazv::ChangeInviteStateAction
Definition: room-model.hpp:73
Kazv::RoomModel::timeline
immer::flex_vector< std::string > timeline
Definition: room-model.hpp:161
Kazv::AddEphemeralAction::events
EventList events
Definition: room-model.hpp:80
Kazv::MarkMembersFullyLoadedAction
Definition: room-model.hpp:92
clientutil.hpp
Kazv::RoomModel::regenerateRelationships
void regenerateRelationships()
Definition: room-model.cpp:456
Kazv::RemovePendingRoomKeyAction
Definition: room-model.hpp:116
Kazv::RoomModel::encrypted
bool encrypted
Definition: room-model.hpp:175
Kazv::operator!=
bool operator!=(BaseJob a, BaseJob b)
Definition: basejob.cpp:292
Kazv::ROOM_TAG_DEFAULT_ORDER
const double ROOM_TAG_DEFAULT_ORDER
Definition: room-model.hpp:141
Kazv::RoomMembership
RoomMembership
Definition: types.hpp:116
Kazv::RoomModel::roomId
std::string roomId
Definition: room-model.hpp:156
Kazv::RoomListModel::rooms
immer::map< std::string, RoomModel > rooms
Definition: room-model.hpp:286
event.hpp
Kazv::RoomListModel::at
auto at(std::string id) const
Definition: room-model.hpp:288
Kazv::RoomModel::hasUser
bool hasUser(std::string userId) const
Definition: room-model.cpp:350
Kazv::UpdateRoomAction::roomAction
RoomAction roomAction
Definition: room-model.hpp:281
Kazv::AddToTimelineAction
Definition: room-model.hpp:54
Kazv::operator==
bool operator==(BaseJob a, BaseJob b)
Definition: basejob.cpp:280
Kazv::RoomModel::knockedMemberEvents
EventList knockedMemberEvents() const
Definition: room-model.cpp:319
Kazv::RoomModel::getPendingRoomKeyEventByTxnId
std::optional< PendingRoomKeyEvent > getPendingRoomKeyEventByTxnId(std::string txnId) const
Definition: room-model.cpp:375
Kazv
Definition: location.hpp:10
Kazv::RoomModel::joinedMemberIds
immer::flex_vector< std::string > joinedMemberIds() const
Definition: room-model.cpp:284
Kazv::MegOlmSessionRotateDesc
Definition: crypto.hpp:26
Kazv::UpdateJoinedMemberCountAction::joinedMemberCount
std::size_t joinedMemberCount
Definition: room-model.hpp:123
Kazv::RoomModel::joinedMemberEvents
EventList joinedMemberEvents() const
Definition: room-model.cpp:309
Kazv::UpdateJoinedMemberCountAction
Definition: room-model.hpp:121
Kazv::RoomListModel::operator[]
auto operator[](std::string id) const
Definition: room-model.hpp:289
Kazv::RoomModel::bannedMemberIds
immer::flex_vector< std::string > bannedMemberIds() const
Definition: room-model.cpp:304
Kazv::RoomModel::makeAddTagEvent
Event makeAddTagEvent(std::string tagId, std::optional< double > order) const
Definition: room-model.cpp:425
Kazv::AddPendingRoomKeyAction
Definition: room-model.hpp:111
Kazv::RoomModel::getLocalEchoByTxnId
std::optional< LocalEchoDesc > getLocalEchoByTxnId(std::string txnId) const
Definition: room-model.cpp:363
Kazv::AddToTimelineAction::prevBatch
std::optional< std::string > prevBatch
Definition: room-model.hpp:58
Kazv::RoomModel::update
static RoomModel update(RoomModel r, Action a)
Definition: room-model.cpp:23
Kazv::PendingRoomKeyEvent::event
Event event
Definition: room-model.hpp:34
Kazv::SetLocalDraftAction
Definition: room-model.hpp:83
Kazv::RoomModel
Definition: room-model.hpp:149
Kazv::PrependTimelineAction::paginateBackToken
std::string paginateBackToken
Definition: room-model.hpp:51
Kazv::RoomModel::ephemeral
immer::map< std::string, Event > ephemeral
Definition: room-model.hpp:171
Kazv::RoomModel::makeRemoveTagEvent
Event makeRemoveTagEvent(std::string tagId) const
Definition: room-model.cpp:437
Kazv::RoomModel::leftMemberEvents
EventList leftMemberEvents() const
Definition: room-model.cpp:324
Kazv::serialize
void serialize(Archive &ar, ClientModel &m, std::uint32_t const version)
Definition: client-model.hpp:586
Kazv::AddPendingRoomKeyAction::pendingRoomKeyEvent
PendingRoomKeyEvent pendingRoomKeyEvent
Definition: room-model.hpp:113
Kazv::AppendTimelineAction
Definition: room-model.hpp:43
Kazv::RoomModel::membersFullyLoaded
bool membersFullyLoaded
Definition: room-model.hpp:182
Kazv::RoomModel::paginateBackToken
std::string paginateBackToken
Definition: room-model.hpp:165
Kazv::RoomModel::joinedMemberCount
std::size_t joinedMemberCount
Definition: room-model.hpp:191
Kazv::RoomModel::canPaginateBack
bool canPaginateBack
whether this room has earlier events to be fetched
Definition: room-model.hpp:167
Kazv::RoomListAction
RoomListModel::Action RoomListAction
Definition: room-model.hpp:298
Kazv::RoomModel::sessionRotateDesc
MegOlmSessionRotateDesc sessionRotateDesc() const
Definition: room-model.cpp:337
local-echo.hpp
Kazv::SetRoomEncryptionAction
Definition: room-model.hpp:88
Kazv::RemoveLocalEchoAction
Definition: room-model.hpp:106
Kazv::AddLocalEchoAction::localEcho
LocalEchoDesc localEcho
Definition: room-model.hpp:103
Kazv::RoomModel::bannedMemberEvents
EventList bannedMemberEvents() const
Definition: room-model.cpp:329
Kazv::RoomModel::Action
std::variant< AddStateEventsAction, AppendTimelineAction, PrependTimelineAction, AddToTimelineAction, AddAccountDataAction, ChangeMembershipAction, ChangeInviteStateAction, AddEphemeralAction, SetLocalDraftAction, SetRoomEncryptionAction, MarkMembersFullyLoadedAction, SetHeroIdsAction, AddLocalEchoAction, RemoveLocalEchoAction, AddPendingRoomKeyAction, RemovePendingRoomKeyAction, UpdateJoinedMemberCountAction, UpdateInvitedMemberCountAction > Action
Definition: room-model.hpp:248
Kazv::AddAccountDataAction::events
immer::flex_vector< Event > events
Definition: room-model.hpp:65
Kazv::UpdateRoomAction::roomId
std::string roomId
Definition: room-model.hpp:280
Kazv::RoomModel::localEchoes
immer::flex_vector< LocalEchoDesc > localEchoes
Definition: room-model.hpp:185
Kazv::RoomModel::generateRelationships
void generateRelationships(EventList newEvents)
Fill in reverseEventRelationships by gathering the relationships specified in newEvents
Definition: room-model.cpp:444
Kazv::RoomModel::inviteState
immer::map< KeyOfState, Event > inviteState
Definition: room-model.hpp:158
Kazv::Event
Definition: event.hpp:20
immer-map.hpp
Kazv::PendingRoomKeyEvent::devices
immer::map< std::string, immer::flex_vector< std::string > > devices
Definition: room-model.hpp:35
Kazv::AddEphemeralAction
Definition: room-model.hpp:78
Kazv::AddStateEventsAction
Definition: room-model.hpp:38
Kazv::AddAccountDataAction
Definition: room-model.hpp:63
Kazv::AddStateEventsAction::stateEvents
immer::flex_vector< Event > stateEvents
Definition: room-model.hpp:40
libkazv-config.hpp
immer-flex-vector.hpp
Kazv::SetLocalDraftAction::localDraft
std::string localDraft
Definition: room-model.hpp:85
Kazv::PendingRoomKeyEvent::txnId
std::string txnId
Definition: room-model.hpp:33
Kazv::RoomAction
RoomModel::Action RoomAction
Definition: room-model.hpp:253
Kazv::PrependTimelineAction
Definition: room-model.hpp:48
Kazv::AppendTimelineAction::events
immer::flex_vector< Event > events
Definition: room-model.hpp:45
Kazv::RoomModel::pendingRoomKeyEvents
immer::flex_vector< PendingRoomKeyEvent > pendingRoomKeyEvents
Definition: room-model.hpp:187
crypto.hpp
Kazv::AddToTimelineAction::limited
std::optional< bool > limited
Definition: room-model.hpp:59
Kazv::SetHeroIdsAction::heroIds
immer::flex_vector< std::string > heroIds
Definition: room-model.hpp:98
sync.hpp
Kazv::RoomModel::accountData
immer::map< std::string, Event > accountData
Definition: room-model.hpp:163
Kazv::RoomListModel
Definition: room-model.hpp:284
Kazv::RoomModel::ReverseEventRelationshipMap
immer::map< std::string, immer::map< std::string, immer::flex_vector< std::string > >> ReverseEventRelationshipMap
Definition: room-model.hpp:154
Kazv::RoomListModel::Action
std::variant< UpdateRoomAction > Action
Definition: room-model.hpp:294
Kazv::RoomModel::invitedMemberIds
immer::flex_vector< std::string > invitedMemberIds() const
Definition: room-model.cpp:289
Kazv::AddToTimelineAction::events
immer::flex_vector< Event > events
Events from oldest to latest.
Definition: room-model.hpp:57
Kazv::EventList
immer::flex_vector< Event > EventList
Definition: types.hpp:96
Kazv::RemovePendingRoomKeyAction::txnId
std::string txnId
Definition: room-model.hpp:118
Kazv::UpdateInvitedMemberCountAction::invitedMemberCount
std::size_t invitedMemberCount
Definition: room-model.hpp:128
Kazv::ChangeMembershipAction::membership
RoomMembership membership
Definition: room-model.hpp:70
Kazv::RoomModel::knockedMemberIds
immer::flex_vector< std::string > knockedMemberIds() const
Definition: room-model.cpp:294
Kazv::RoomListModel::has
bool has(std::string id) const
Definition: room-model.hpp:290
Kazv::SetHeroIdsAction
Definition: room-model.hpp:96
Kazv::RoomModel::timelineGaps
immer::map< std::string, std::string > timelineGaps
Definition: room-model.hpp:169
immer-array.hpp
Kazv::RemoveLocalEchoAction::txnId
std::string txnId
Definition: room-model.hpp:108
Kazv::LocalEchoDesc
Describes a local echo.
Definition: local-echo.hpp:18
Kazv::UpdateRoomAction
Definition: room-model.hpp:278
Kazv::UpdateInvitedMemberCountAction
Definition: room-model.hpp:126
Kazv::RoomModel::leftMemberIds
immer::flex_vector< std::string > leftMemberIds() const
Definition: room-model.cpp:299