libkazv
client.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of libkazv.
3  * SPDX-FileCopyrightText: 2020-2023 tusooa <tusooa@kazv.moe>
4  * SPDX-License-Identifier: AGPL-3.0-or-later
5  */
6 
7 #pragma once
8 #include <libkazv-config.hpp>
9 
10 #include <lager/reader.hpp>
11 #include <immer/box.hpp>
12 #include <immer/map.hpp>
13 #include <immer/flex_vector.hpp>
14 #include <immer/flex_vector_transient.hpp>
15 
16 #include "sdk-model.hpp"
17 #include "client/client-model.hpp"
19 #include "sdk-model-cursor-tag.hpp"
20 #include "get-content-job-v1.hpp"
21 
22 #include "room/room.hpp"
23 #include "notification-handler.hpp"
24 
25 namespace Kazv
26 {
59  class Client
60  {
61  public:
63 
65 #ifdef KAZV_USE_THREAD_SAFETY_HELPER
66  , EventLoopThreadIdKeeper &
67 #endif
68 
69  >;
72 
74 
75  struct InEventLoopTag {};
84  Client(lager::reader<SdkModel> sdk,
85  ContextT ctx, std::nullopt_t);
86 
97  Client(lager::reader<SdkModel> sdk,
98  ContextWithDepsT ctx);
99 
111  ContextWithDepsT ctx);
112 
123  Client(InEventLoopTag, ContextT ctx, DepsT deps);
124 
125 
136  Client toEventLoop() const;
137 
138  /* lager::reader<immer::map<std::string, Room>> */
139  inline auto rooms() const {
140  return clientCursor()
143  }
144 
145  /* lager::reader<RangeT<std::string>> */
146  inline auto roomIds() const {
147  return rooms().xform(
148  zug::map([](auto m) {
149  return intoImmer(
150  immer::flex_vector<std::string>{},
151  zug::map([](auto val) { return val.first; }),
152  m);
153  }));
154  }
155 
156  auto roomIdsUnderTag(std::string tagId) const -> lager::reader<immer::map<std::string, double>>;
157 
164  auto roomIdsByTagId() const -> lager::reader<immer::map<std::string, immer::map<std::string, double>>>;
165 
166  KAZV_WRAP_ATTR(ClientModel, clientCursor(), serverUrl)
167  KAZV_WRAP_ATTR(ClientModel, clientCursor(), loggedIn)
168  KAZV_WRAP_ATTR(ClientModel, clientCursor(), userId)
169  KAZV_WRAP_ATTR(ClientModel, clientCursor(), token)
170  KAZV_WRAP_ATTR(ClientModel, clientCursor(), deviceId)
171  KAZV_WRAP_ATTR(ClientModel, clientCursor(), toDevice)
172 
181  Room room(std::string id) const;
182 
208  Room roomByCursor(lager::reader<std::string> id) const;
209 
227  PromiseT passwordLogin(std::string homeserver, std::string username,
228  std::string password, std::string deviceName) const;
229 
245  PromiseT tokenLogin(std::string homeserver, std::string username,
246  std::string token, std::string deviceId) const;
247 
253  auto shouldSync() const -> lager::reader<bool>;
254 
262  PromiseT logout() const;
263 
277  PromiseT autoDiscover(std::string userId) const;
278 
297  RoomVisibility v,
298  std::optional<std::string> name = {},
299  std::optional<std::string> alias = {},
300  immer::array<std::string> invite = {},
301  std::optional<bool> isDirect = {},
302  bool allowFederate = true,
303  std::optional<std::string> topic = {},
304  JsonWrap powerLevelContentOverride = json::object(),
305  std::optional<CreateRoomPreset> preset = std::nullopt,
306  immer::array<Event> initialState = immer::array<Event>()
307  ) const;
308 
316  PromiseT joinRoomById(std::string roomId) const;
317 
327  PromiseT joinRoom(std::string roomId, immer::array<std::string> serverName) const;
328 
341  PromiseT uploadContent(immer::box<Bytes> content,
342  std::string uploadId,
343  std::optional<std::string> filename = std::nullopt,
344  std::optional<std::string> contentType = std::nullopt) const;
345 
355  PromiseT uploadContent(FileDesc file) const;
356 
357 
368  inline std::string mxcUriToHttp(std::string mxcUri) const {
369  using namespace CursorOp;
370  auto [serverName, mediaId] = mxcUriToMediaDesc(mxcUri);
371  return (+clientCursor())
372  .template job<GetContentJob>()
373  .make(serverName, mediaId).url();
374  }
375 
386  std::string mxcUriToHttpV1(std::string mxcUri) const;
387 
402  PromiseT downloadContent(std::string mxcUri,
403  std::optional<FileDesc> downloadTo = std::nullopt) const;
404 
422  PromiseT downloadThumbnail(std::string mxcUri,
423  int width,
424  int height,
425  std::optional<ThumbnailResizingMethod> method = std::nullopt,
426  std::optional<FileDesc> downloadTo = std::nullopt) const;
427 
437  PromiseT getProfile(std::string userId) const;
438 
446  PromiseT setAvatarUrl(std::optional<std::string> avatarUrl) const;
447 
455  PromiseT setDisplayName(std::optional<std::string> displayName) const;
456 
457  // lager::reader<bool>
458  inline auto syncing() const {
459  return clientCursor()[&ClientModel::syncing];
460  }
461 
473  PromiseT startSyncing() const;
474 
482  PromiseT stopSyncing() const;
483 
491  auto devicesOfUser(std::string userId) const -> lager::reader<immer::flex_vector<DeviceKeyInfo>>;
492 
501  PromiseT setDeviceTrustLevel(std::string userId, std::string deviceId, DeviceTrustLevel trustLevel) const;
502 
508  auto trustLevelNeededToSendKeys() const -> lager::reader<DeviceTrustLevel>;
509 
518 
524  auto directRoomMap() const -> lager::reader<immer::map<std::string, std::string>>;
525 
531  auto accountData() const -> lager::reader<immer::map<std::string, Event>>;
532 
539  PromiseT setAccountData(Event accountDataEvent) const;
540 
547 
564  template<class Archive>
565  void serializeTo(Archive &ar) const {
566  ar << sdkCursor().get();
567  }
568 
576  PromiseT getVersions(std::string homeserver) const;
577 
585  auto supportVersions() const -> lager::reader<immer::array<std::string>>;
586 
587  private:
588  void syncForever(std::optional<int> retryTime = std::nullopt) const;
589 
590  const lager::reader<SdkModel> &sdkCursor() const;
591  lager::reader<ClientModel> clientCursor() const;
592 
593  std::optional<lager::reader<SdkModel>> m_sdk;
594  std::optional<lager::reader<ClientModel>> m_client;
595  ContextT m_ctx;
596  std::optional<DepsT> m_deps;
597  KAZV_DECLARE_THREAD_ID();
598  KAZV_DECLARE_EVENT_LOOP_THREAD_ID_KEEPER(m_deps.has_value() ? &lager::get<EventLoopThreadIdKeeper &>(m_deps.value()) : 0);
599  };
600 
601 }
Represent a Matrix client.
Definition: client.hpp:60
auto directRoomMap() const -> lager::reader< immer::map< std::string, std::string >>
Get the map from direct messaging room ids to user ids.
Definition: client.cpp:429
PromiseT setAccountData(Event accountDataEvent) const
Set the account data that is not associated with any room.
Definition: client.cpp:451
PromiseT setDisplayName(std::optional< std::string > displayName) const
Change the display name of the current user.
Definition: client.cpp:395
Room roomByCursor(lager::reader< std::string > id) const
Get the room with id.
Definition: client.cpp:74
PromiseT setTrustLevelNeededToSendKeys(DeviceTrustLevel trustLevel) const
Set the trust level needed to send keys to a device.
Definition: client.cpp:424
lager::deps< JobInterface &, EventInterface &, SdkModelCursorKey, RandomInterface & > DepsT
Definition: client.hpp:69
PromiseT getVersions(std::string homeserver) const
Get all supported versions.
Definition: client.cpp:461
PromiseT joinRoomById(std::string roomId) const
Join a room by its id.
Definition: client.cpp:182
PromiseT joinRoom(std::string roomId, immer::array< std::string > serverName) const
Join a room by its id or alias.
Definition: client.cpp:187
std::string mxcUriToHttp(std::string mxcUri) const
Convert a MXC URI to an HTTP(s) URI.
Definition: client.hpp:368
auto trustLevelNeededToSendKeys() const -> lager::reader< DeviceTrustLevel >
Get the trust level needed to send keys to a device.
Definition: client.cpp:419
NotificationHandler notificationHandler() const
Get a notification handler that works on this Client.
Definition: client.cpp:456
Client toEventLoop() const
Create a Client that is not constructed from a cursor.
Definition: client.cpp:59
auto syncing() const
Definition: client.hpp:458
PromiseT setAvatarUrl(std::optional< std::string > avatarUrl) const
Change the avatar url of the current user.
Definition: client.cpp:390
SingleTypePromise< DefaultRetType > PromiseT
Definition: client.hpp:73
PromiseT logout() const
Stop syncing and then logout current session.
Definition: client.cpp:123
std::string mxcUriToHttpV1(std::string mxcUri) const
Convert a MXC URI to an HTTP(s) URI that needs Authorization.
Definition: client.cpp:219
auto roomIds() const
Definition: client.hpp:146
Context< ActionT > ContextT
Definition: client.hpp:70
PromiseT downloadContent(std::string mxcUri, std::optional< FileDesc > downloadTo=std::nullopt) const
Download content from the content repository.
Definition: client.cpp:227
PromiseT stopSyncing() const
Stop the indefinite syncing.
Definition: client.cpp:356
void serializeTo(Archive &ar) const
Serialize the model to a Boost.Serialization archive.
Definition: client.hpp:565
auto shouldSync() const -> lager::reader< bool >
Get the shouldSync field of current ClientModel.
Definition: client.cpp:119
auto roomIdsUnderTag(std::string tagId) const -> lager::reader< immer::map< std::string, double >>
Definition: client.cpp:434
PromiseT setDeviceTrustLevel(std::string userId, std::string deviceId, DeviceTrustLevel trustLevel) const
Set the trust level of a device.
Definition: client.cpp:414
Room room(std::string id) const
Get the room with id .
Definition: client.cpp:65
ClientAction ActionT
Definition: client.hpp:62
PromiseT autoDiscover(std::string userId) const
Automatically discover the homeserver for userId.
Definition: client.cpp:131
auto supportVersions() const -> lager::reader< immer::array< std::string >>
Get all supported versions.
Definition: client.cpp:466
PromiseT tokenLogin(std::string homeserver, std::string username, std::string token, std::string deviceId) const
Login using token and deviceId.
Definition: client.cpp:102
Client(lager::reader< SdkModel > sdk, ContextT ctx, std::nullopt_t)
Constructor.
Definition: client.cpp:17
PromiseT uploadContent(immer::box< Bytes > content, std::string uploadId, std::optional< std::string > filename=std::nullopt, std::optional< std::string > contentType=std::nullopt) const
Upload content to the content repository.
Definition: client.cpp:193
auto roomIdsByTagId() const -> lager::reader< immer::map< std::string, immer::map< std::string, double >>>
Get the room ids under all tags.
Definition: client.cpp:441
PromiseT downloadThumbnail(std::string mxcUri, int width, int height, std::optional< ThumbnailResizingMethod > method=std::nullopt, std::optional< FileDesc > downloadTo=std::nullopt) const
Download a thumbnail from the content repository.
Definition: client.cpp:233
PromiseT getProfile(std::string userId) const
Fetch the profile of a user.
Definition: client.cpp:385
PromiseT createRoom(RoomVisibility v, std::optional< std::string > name={}, std::optional< std::string > alias={}, immer::array< std::string > invite={}, std::optional< bool > isDirect={}, bool allowFederate=true, std::optional< std::string > topic={}, JsonWrap powerLevelContentOverride=json::object(), std::optional< CreateRoomPreset > preset=std::nullopt, immer::array< Event > initialState=immer::array< Event >()) const
Create a room.
Definition: client.cpp:150
auto devicesOfUser(std::string userId) const -> lager::reader< immer::flex_vector< DeviceKeyInfo >>
Get the info of all devices of user userId that supports encryption.
Definition: client.cpp:400
PromiseT passwordLogin(std::string homeserver, std::string username, std::string password, std::string deviceName) const
Login using the password.
Definition: client.cpp:83
auto accountData() const -> lager::reader< immer::map< std::string, Event >>
Get the account data that is not associated with any room.
Definition: client.cpp:446
PromiseT startSyncing() const
Start syncing if the Client is not syncing.
Definition: client.cpp:244
auto rooms() const
Definition: client.hpp:139
Definition: context.hpp:130
Definition: eventinterface.hpp:15
Definition: event.hpp:21
A class to handle a notification.
Definition: notification-handler.hpp:22
Definition: random-generator.hpp:16
Represent a Matrix room.
Definition: room.hpp:38
Definition: promise-interface.hpp:122
#define KAZV_WRAP_ATTR(_type, _d, _attr)
Definition: clientutil.hpp:229
Definition: location.hpp:10
std::variant< RoomListAction, LoginAction, TokenLoginAction, LogoutAction, HardLogoutAction, GetWellknownAction, GetVersionsAction, SyncAction, SetShouldSyncAction, PostInitialFiltersAction, SetAccountDataAction, PaginateTimelineAction, SendMessageAction, SendStateEventAction, SaveLocalEchoAction, UpdateLocalEchoStatusAction, RedactEventAction, CreateRoomAction, GetRoomStatesAction, GetStateEventAction, InviteToRoomAction, JoinRoomByIdAction, JoinRoomAction, LeaveRoomAction, ForgetRoomAction, KickAction, BanAction, UnbanAction, SetAccountDataPerRoomAction, ProcessResponseAction, SetTypingAction, PostReceiptAction, SetReadMarkerAction, UploadContentAction, DownloadContentAction, DownloadThumbnailAction, SendToDeviceMessageAction, SendMultipleToDeviceMessagesAction, UploadIdentityKeysAction, GenerateAndUploadOneTimeKeysAction, QueryKeysAction, ClaimKeysAction, EncryptMegOlmEventAction, SetDeviceTrustLevelAction, SetTrustLevelNeededToSendKeysAction, PrepareForSharingRoomKeyAction, GetUserProfileAction, SetAvatarUrlAction, SetDisplayNameAction, ResubmitJobAction > ClientAction
Definition: clientfwd.hpp:145
RoomVisibility
Definition: client-model.hpp:40
DeviceTrustLevel
Definition: device-list-tracker.hpp:27
lager::dep::key< SdkModelCursorTag, lager::dep::fn< std::shared_ptr< lager::reader< SdkModel > >> > SdkModelCursorKey
Definition: sdk-model-cursor-tag.hpp:23
detail::IntoImmerT intoImmer
Definition: cursorutil.hpp:88
std::pair< std::string, std::string > mxcUriToMediaDesc(std::string mxcUri)
Definition: content.cpp:17
Definition: clientutil.hpp:217
Definition: client-model.hpp:59
RoomListModel roomList
Definition: client-model.hpp:76
bool syncing
Definition: client-model.hpp:66
Definition: client.hpp:75
Definition: jobinterface.hpp:21
immer::map< std::string, RoomModel > rooms
Definition: room-model.hpp:399
Definition: sdk-model.hpp:26