diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h index 6e6b33a5e..57ea9d6b3 100644 --- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h +++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h @@ -29,6 +29,7 @@ struct ConnectedBotState { QString link; TimeId date = 0; int users = 0; + bool unresolved = false; bool revoked = false; }; struct ConnectedBot { diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.cpp b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.cpp index 984e94f09..3f879e5a1 100644 --- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.cpp +++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "base/timer_rpl.h" #include "base/unixtime.h" +#include "base/weak_ptr.h" #include "boxes/peer_list_box.h" #include "core/click_handler_types.h" #include "data/data_session.h" @@ -55,10 +56,12 @@ enum class JoinType { Suggested, }; -class ListController final : public PeerListController { +class ListController final + : public PeerListController + , public base::has_weak_ptr { public: ListController( - not_null controller, + not_null controller, not_null peer, JoinType type); ~ListController(); @@ -78,12 +81,15 @@ public: private: [[nodiscard]] std::unique_ptr createRow(ConnectedBot bot); + void open(not_null bot, ConnectedBotState state); - const not_null _controller; + const not_null _controller; const not_null _peer; const JoinType _type = {}; base::flat_map, ConnectedBotState> _states; + base::flat_set> _resolving; + UserData *_openOnResolve = nullptr; mtpRequestId _requestId = 0; TimeId _offsetDate = 0; @@ -94,8 +100,27 @@ private: }; +void Resolve( + not_null peer, + not_null bot, + Fn)> done) { + peer->session().api().request(MTPpayments_GetConnectedStarRefBot( + peer->input, + bot->inputUser + )).done([=](const MTPpayments_ConnectedStarRefBots &result) { + const auto parsed = Parse(&peer->session(), result); + if (parsed.empty()) { + done(std::nullopt); + } else { + done(parsed.front().state); + } + }).fail([=] { + done(std::nullopt); + }).send(); +} + ListController::ListController( - not_null controller, + not_null controller, not_null peer, JoinType type) : PeerListController() @@ -136,7 +161,7 @@ std::unique_ptr ListController::createRow(ConnectedBot bot) { void ListController::prepare() { delegate()->peerListSetTitle((_type == JoinType::Joined) ? tr::lng_star_ref_list_my() - : tr::lng_star_ref_list_subtitle()); + : tr::lng_star_ref_list_title()); loadMoreRows(); } @@ -198,6 +223,7 @@ void ListController::loadMoreRows() { .commission = ushort(commission), .durationMonths = uchar(durationMonths), }, + .unresolved = true, }, })); } @@ -219,12 +245,35 @@ void ListController::rowClicked(not_null row) { const auto bot = row->peer()->asUser(); const auto i = _states.find(bot); Assert(i != end(_states)); - const auto state = i->second; - const auto window = _controller->parentController(); - if (_type == JoinType::Joined || !state.link.isEmpty()) { - window->show(StarRefLinkBox({ bot, state }, _peer)); + if (i->second.unresolved) { + if (!_resolving.emplace(bot).second) { + return; + } + _openOnResolve = bot; + const auto resolved = [=](std::optional state) { + _resolving.remove(bot); + auto &now = _states[bot]; + if (state) { + now = *state; + } else { + now.unresolved = false; + } + if (_openOnResolve == bot) { + open(bot, now); + } + }; + Resolve(_peer, bot, crl::guard(this, resolved)); } else { - window->show(JoinStarRefBox({ bot, state }, _peer)); + _openOnResolve = nullptr; + open(bot, i->second); + } +} + +void ListController::open(not_null bot, ConnectedBotState state) { + if (_type == JoinType::Joined || !state.link.isEmpty()) { + _controller->show(StarRefLinkBox({ bot, state }, _peer)); + } else { + _controller->show(JoinStarRefBox({ bot, state }, _peer)); } } @@ -244,12 +293,11 @@ base::unique_qptr ListController::rowContextMenu( const auto addAction = Ui::Menu::CreateAddActionCallback(result.get()); addAction(tr::lng_star_ref_list_my_open(tr::now), [=] { - _controller->parentController()->showPeerHistory(bot); + _controller->showPeerHistory(bot); }, &st::menuIconBot); addAction(tr::lng_star_ref_list_my_copy(tr::now), [=] { QApplication::clipboard()->setText(state.link); - _controller->parentController()->showToast( - tr::lng_username_copied(tr::now)); + _controller->showToast(tr::lng_username_copied(tr::now)); }, &st::menuIconLinks); const auto revoke = [=] { session().api().request(MTPpayments_EditConnectedStarRefBot( @@ -257,9 +305,9 @@ base::unique_qptr ListController::rowContextMenu( _peer->input, MTP_string(state.link) )).done([=] { - _controller->parentController()->showToast(u"Revoked!"_q); + _controller->showToast(u"Revoked!"_q); }).fail([=](const MTP::Error &error) { - _controller->parentController()->showToast(u"Failed: "_q + error.type()); + _controller->showToast(u"Failed: "_q + error.type()); }).send(); }; addAction({ @@ -351,7 +399,7 @@ void InnerWidget::setupMy() { PeerListContentDelegateSimple >(); const auto controller = lifetime().make_state( - _controller, + _controller->parentController(), peer(), JoinType::Joined); const auto content = inner->add( @@ -375,7 +423,7 @@ void InnerWidget::setupSuggested() { PeerListContentDelegateSimple >(); auto controller = lifetime().make_state( - _controller, + _controller->parentController(), peer(), JoinType::Suggested); const auto content = _container->add( @@ -615,5 +663,21 @@ std::shared_ptr Make(not_null peer) { std::make_shared(peer))); } +object_ptr ProgramsListBox( + not_null controller, + not_null peer) { + const auto initBox = [=](not_null box) { + box->addButton(tr::lng_close(), [=] { + box->closeBox(); + }); + }; + return Box( + std::make_unique( + controller, + peer, + JoinType::Suggested), + initBox); +} + } // namespace Info::BotStarRef::Join diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.h b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.h index 129caed9f..6f5ff630f 100644 --- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.h +++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.h @@ -19,8 +19,13 @@ class FadeWrap; class IconButton; class AbstractButton; class VerticalLayout; +class BoxContent; } // namespace Ui +namespace Window { +class SessionController; +} // namespace Window + namespace Info::BotStarRef::Join { class InnerWidget; @@ -76,4 +81,8 @@ private: [[nodiscard]] std::shared_ptr Make(not_null peer); +[[nodiscard]] object_ptr ProgramsListBox( + not_null controller, + not_null peer); + } // namespace Info::BotStarRef::Join diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_setup_widget.cpp b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_setup_widget.cpp index 87e402ffd..c589520f2 100644 --- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_setup_widget.cpp +++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_setup_widget.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/click_handler_types.h" #include "data/data_user.h" #include "info/bot/starref/info_bot_starref_common.h" +#include "info/bot/starref/info_bot_starref_join_widget.h" #include "info/profile/info_profile_icon.h" #include "info/info_controller.h" #include "info/info_memento.h" @@ -554,7 +555,8 @@ void InnerWidget::setupViewExisting() { tr::lng_star_ref_existing_title(), tr::lng_star_ref_existing_about()); button->setClickedCallback([=] { - _controller->showToast(u"List or smth.."_q); + const auto window = _controller->parentController(); + window->show(Join::ProgramsListBox(window, peer())); }); Ui::AddSkip(_container);