// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once #include "td/telegram/ChannelId.h" #include "td/telegram/GroupCallId.h" #include "td/telegram/InputGroupCallId.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" #include "td/actor/actor.h" #include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/Status.h" #include namespace td { class Td; class GroupCallManager : public Actor { public: GroupCallManager(Td *td, ActorShared<> parent); GroupCallManager(const GroupCallManager &) = delete; GroupCallManager &operator=(const GroupCallManager &) = delete; GroupCallManager(GroupCallManager &&) = delete; GroupCallManager &operator=(GroupCallManager &&) = delete; ~GroupCallManager() override; GroupCallId get_group_call_id(InputGroupCallId input_group_call_id, ChannelId channel_id); void create_voice_chat(ChannelId channel_id, Promise &&promise); void get_group_call(GroupCallId group_call_id, Promise> &&promise); void join_group_call(GroupCallId group_call_id, td_api::object_ptr &&payload, int32 source, bool is_muted, Promise> &&promise); void toggle_group_call_mute_new_members(GroupCallId group_call_id, bool mute_new_members, Promise &&promise); void invite_group_call_members(GroupCallId group_call_id, vector &&user_ids, Promise &&promise); void set_group_call_member_is_speaking(GroupCallId group_call_id, int32 source, bool is_speaking, Promise &&promise); void toggle_group_call_member_is_muted(GroupCallId group_call_id, UserId user_id, bool is_muted, Promise &&promise); void check_group_call_is_joined(GroupCallId group_call_id, Promise &&promise); void leave_group_call(GroupCallId group_call_id, Promise &&promise); void discard_group_call(GroupCallId group_call_id, Promise &&promise); void on_update_group_call(tl_object_ptr group_call_ptr, ChannelId channel_id); void on_user_speaking_in_group_call(GroupCallId group_call_id, UserId user_id, int32 date); void process_join_group_call_response(InputGroupCallId input_group_call_id, uint64 generation, tl_object_ptr &&updates, Promise &&promise); private: struct GroupCall; struct GroupCallRecentSpeakers; struct PendingJoinRequest; static constexpr int32 RECENT_SPEAKER_TIMEOUT = 5 * 60; void tear_down() override; static void on_pending_send_speaking_action_timeout_callback(void *group_call_manager_ptr, int64 group_call_id_int); void on_send_speaking_action_timeout(GroupCallId group_call_id); static void on_recent_speaker_update_timeout_callback(void *group_call_manager_ptr, int64 group_call_id_int); void on_recent_speaker_update_timeout(GroupCallId group_call_id); Result get_input_group_call_id(GroupCallId group_call_id); GroupCallId get_next_group_call_id(InputGroupCallId input_group_call_id); GroupCall *add_group_call(InputGroupCallId input_group_call_id, ChannelId channel_id); const GroupCall *get_group_call(InputGroupCallId input_group_call_id) const; GroupCall *get_group_call(InputGroupCallId input_group_call_id); void reload_group_call(InputGroupCallId input_group_call_id, Promise> &&promise); void finish_get_group_call(InputGroupCallId input_group_call_id, Result> &&result); bool on_join_group_call_response(InputGroupCallId input_group_call_id, string json_response); void finish_join_group_call(InputGroupCallId input_group_call_id, uint64 generation, Status error); void on_group_call_left(InputGroupCallId input_group_call_id, int32 source); InputGroupCallId update_group_call(const tl_object_ptr &group_call_ptr, ChannelId channel_id); void on_group_call_recent_speakers_updated(const GroupCall *group_call, GroupCallRecentSpeakers *recent_speakers); static Result> get_group_call_join_response_object( string json_response); tl_object_ptr get_update_group_call_object(const GroupCall *group_call) const; tl_object_ptr get_group_call_object(const GroupCall *group_call, bool for_update = false) const; Td *td_; ActorShared<> parent_; GroupCallId max_group_call_id_; vector input_group_call_ids_; std::unordered_map, InputGroupCallIdHash> group_calls_; std::unordered_map, GroupCallIdHash> group_call_recent_speakers_; std::unordered_map>>, InputGroupCallIdHash> load_group_call_queries_; std::unordered_map, InputGroupCallIdHash> pending_join_requests_; uint64 join_group_request_generation_ = 0; MultiTimeout pending_send_speaking_action_timeout_{"PendingSendSpeakingActionTimeout"}; mutable MultiTimeout recent_speaker_update_timeout_{"RecentSpeakerUpdateTimeout"}; }; } // namespace td