// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // 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/DialogId.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" #include "td/utils/Promise.h" #include "td/utils/Status.h" #include namespace td { class Td; class ChannelRecommendationManager final : public Actor { public: ChannelRecommendationManager(Td *td, ActorShared<> parent); void get_recommended_channels(Promise> &&promise); void get_channel_recommendations(DialogId dialog_id, bool return_local, Promise> &&chats_promise, Promise> &&count_promise); void open_channel_recommended_channel(DialogId dialog_id, DialogId opened_dialog_id, Promise &&promise); void memory_stats(vector &output); private: static constexpr int32 CHANNEL_RECOMMENDATIONS_CACHE_TIME = 86400; // some reasonable limit struct RecommendedDialogs { int32 total_count_ = 0; vector dialog_ids_; double next_reload_time_ = 0.0; template void store(StorerT &storer) const; template void parse(ParserT &parser); }; void tear_down() final; bool is_suitable_recommended_channel(DialogId dialog_id) const; bool is_suitable_recommended_channel(ChannelId channel_id) const; bool are_suitable_recommended_dialogs(const RecommendedDialogs &recommended_dialogs) const; static string get_recommended_channels_database_key(); void load_recommended_channels(bool use_database, Promise> &&promise); void fail_load_recommended_channels_queries(Status &&error); void finish_load_recommended_channels_queries(int32 total_count, vector dialog_ids); void on_load_recommended_channels_from_database(string value); void reload_recommended_channels(); void on_get_recommended_channels(Result>>> &&r_chats); static string get_channel_recommendations_database_key(ChannelId channel_id); void load_channel_recommendations(ChannelId channel_id, bool use_database, bool return_local, Promise> &&chats_promise, Promise> &&count_promise); void fail_load_channel_recommendations_queries(ChannelId channel_id, Status &&error); void finish_load_channel_recommendations_queries(ChannelId channel_id, int32 total_count, vector dialog_ids); void on_load_channel_recommendations_from_database(ChannelId channel_id, string value); void reload_channel_recommendations(ChannelId channel_id); void on_get_channel_recommendations( ChannelId channel_id, Result>>> &&r_chats); FlatHashMap channel_recommended_dialogs_; FlatHashMap>>, ChannelIdHash> get_channel_recommendations_queries_; FlatHashMap>>, ChannelIdHash> get_channel_recommendation_count_queries_[2]; RecommendedDialogs recommended_channels_; vector>> get_recommended_channels_queries_; bool are_recommended_channels_inited_ = false; Td *td_; ActorShared<> parent_; }; } // namespace td