Show list of programs in View Existing.

This commit is contained in:
John Preston 2024-11-29 15:04:25 +04:00
parent 824237deb3
commit 86ea760011
4 changed files with 94 additions and 18 deletions

View file

@ -29,6 +29,7 @@ struct ConnectedBotState {
QString link; QString link;
TimeId date = 0; TimeId date = 0;
int users = 0; int users = 0;
bool unresolved = false;
bool revoked = false; bool revoked = false;
}; };
struct ConnectedBot { struct ConnectedBot {

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h" #include "apiwrap.h"
#include "base/timer_rpl.h" #include "base/timer_rpl.h"
#include "base/unixtime.h" #include "base/unixtime.h"
#include "base/weak_ptr.h"
#include "boxes/peer_list_box.h" #include "boxes/peer_list_box.h"
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "data/data_session.h" #include "data/data_session.h"
@ -55,10 +56,12 @@ enum class JoinType {
Suggested, Suggested,
}; };
class ListController final : public PeerListController { class ListController final
: public PeerListController
, public base::has_weak_ptr {
public: public:
ListController( ListController(
not_null<Controller*> controller, not_null<Window::SessionController*> controller,
not_null<PeerData*> peer, not_null<PeerData*> peer,
JoinType type); JoinType type);
~ListController(); ~ListController();
@ -78,12 +81,15 @@ public:
private: private:
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(ConnectedBot bot); [[nodiscard]] std::unique_ptr<PeerListRow> createRow(ConnectedBot bot);
void open(not_null<UserData*> bot, ConnectedBotState state);
const not_null<Controller*> _controller; const not_null<Window::SessionController*> _controller;
const not_null<PeerData*> _peer; const not_null<PeerData*> _peer;
const JoinType _type = {}; const JoinType _type = {};
base::flat_map<not_null<PeerData*>, ConnectedBotState> _states; base::flat_map<not_null<PeerData*>, ConnectedBotState> _states;
base::flat_set<not_null<PeerData*>> _resolving;
UserData *_openOnResolve = nullptr;
mtpRequestId _requestId = 0; mtpRequestId _requestId = 0;
TimeId _offsetDate = 0; TimeId _offsetDate = 0;
@ -94,8 +100,27 @@ private:
}; };
void Resolve(
not_null<PeerData*> peer,
not_null<UserData*> bot,
Fn<void(std::optional<ConnectedBotState>)> 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( ListController::ListController(
not_null<Controller*> controller, not_null<Window::SessionController*> controller,
not_null<PeerData*> peer, not_null<PeerData*> peer,
JoinType type) JoinType type)
: PeerListController() : PeerListController()
@ -136,7 +161,7 @@ std::unique_ptr<PeerListRow> ListController::createRow(ConnectedBot bot) {
void ListController::prepare() { void ListController::prepare() {
delegate()->peerListSetTitle((_type == JoinType::Joined) delegate()->peerListSetTitle((_type == JoinType::Joined)
? tr::lng_star_ref_list_my() ? tr::lng_star_ref_list_my()
: tr::lng_star_ref_list_subtitle()); : tr::lng_star_ref_list_title());
loadMoreRows(); loadMoreRows();
} }
@ -198,6 +223,7 @@ void ListController::loadMoreRows() {
.commission = ushort(commission), .commission = ushort(commission),
.durationMonths = uchar(durationMonths), .durationMonths = uchar(durationMonths),
}, },
.unresolved = true,
}, },
})); }));
} }
@ -219,12 +245,35 @@ void ListController::rowClicked(not_null<PeerListRow*> row) {
const auto bot = row->peer()->asUser(); const auto bot = row->peer()->asUser();
const auto i = _states.find(bot); const auto i = _states.find(bot);
Assert(i != end(_states)); Assert(i != end(_states));
const auto state = i->second; if (i->second.unresolved) {
const auto window = _controller->parentController(); if (!_resolving.emplace(bot).second) {
if (_type == JoinType::Joined || !state.link.isEmpty()) { return;
window->show(StarRefLinkBox({ bot, state }, _peer)); }
_openOnResolve = bot;
const auto resolved = [=](std::optional<ConnectedBotState> 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 { } else {
window->show(JoinStarRefBox({ bot, state }, _peer)); _openOnResolve = nullptr;
open(bot, i->second);
}
}
void ListController::open(not_null<UserData*> 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<Ui::PopupMenu> ListController::rowContextMenu(
const auto addAction = Ui::Menu::CreateAddActionCallback(result.get()); const auto addAction = Ui::Menu::CreateAddActionCallback(result.get());
addAction(tr::lng_star_ref_list_my_open(tr::now), [=] { addAction(tr::lng_star_ref_list_my_open(tr::now), [=] {
_controller->parentController()->showPeerHistory(bot); _controller->showPeerHistory(bot);
}, &st::menuIconBot); }, &st::menuIconBot);
addAction(tr::lng_star_ref_list_my_copy(tr::now), [=] { addAction(tr::lng_star_ref_list_my_copy(tr::now), [=] {
QApplication::clipboard()->setText(state.link); QApplication::clipboard()->setText(state.link);
_controller->parentController()->showToast( _controller->showToast(tr::lng_username_copied(tr::now));
tr::lng_username_copied(tr::now));
}, &st::menuIconLinks); }, &st::menuIconLinks);
const auto revoke = [=] { const auto revoke = [=] {
session().api().request(MTPpayments_EditConnectedStarRefBot( session().api().request(MTPpayments_EditConnectedStarRefBot(
@ -257,9 +305,9 @@ base::unique_qptr<Ui::PopupMenu> ListController::rowContextMenu(
_peer->input, _peer->input,
MTP_string(state.link) MTP_string(state.link)
)).done([=] { )).done([=] {
_controller->parentController()->showToast(u"Revoked!"_q); _controller->showToast(u"Revoked!"_q);
}).fail([=](const MTP::Error &error) { }).fail([=](const MTP::Error &error) {
_controller->parentController()->showToast(u"Failed: "_q + error.type()); _controller->showToast(u"Failed: "_q + error.type());
}).send(); }).send();
}; };
addAction({ addAction({
@ -351,7 +399,7 @@ void InnerWidget::setupMy() {
PeerListContentDelegateSimple PeerListContentDelegateSimple
>(); >();
const auto controller = lifetime().make_state<ListController>( const auto controller = lifetime().make_state<ListController>(
_controller, _controller->parentController(),
peer(), peer(),
JoinType::Joined); JoinType::Joined);
const auto content = inner->add( const auto content = inner->add(
@ -375,7 +423,7 @@ void InnerWidget::setupSuggested() {
PeerListContentDelegateSimple PeerListContentDelegateSimple
>(); >();
auto controller = lifetime().make_state<ListController>( auto controller = lifetime().make_state<ListController>(
_controller, _controller->parentController(),
peer(), peer(),
JoinType::Suggested); JoinType::Suggested);
const auto content = _container->add( const auto content = _container->add(
@ -615,5 +663,21 @@ std::shared_ptr<Info::Memento> Make(not_null<PeerData*> peer) {
std::make_shared<Memento>(peer))); std::make_shared<Memento>(peer)));
} }
object_ptr<Ui::BoxContent> ProgramsListBox(
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer) {
const auto initBox = [=](not_null<PeerListBox*> box) {
box->addButton(tr::lng_close(), [=] {
box->closeBox();
});
};
return Box<PeerListBox>(
std::make_unique<ListController>(
controller,
peer,
JoinType::Suggested),
initBox);
}
} // namespace Info::BotStarRef::Join } // namespace Info::BotStarRef::Join

View file

@ -19,8 +19,13 @@ class FadeWrap;
class IconButton; class IconButton;
class AbstractButton; class AbstractButton;
class VerticalLayout; class VerticalLayout;
class BoxContent;
} // namespace Ui } // namespace Ui
namespace Window {
class SessionController;
} // namespace Window
namespace Info::BotStarRef::Join { namespace Info::BotStarRef::Join {
class InnerWidget; class InnerWidget;
@ -76,4 +81,8 @@ private:
[[nodiscard]] std::shared_ptr<Info::Memento> Make(not_null<PeerData*> peer); [[nodiscard]] std::shared_ptr<Info::Memento> Make(not_null<PeerData*> peer);
[[nodiscard]] object_ptr<Ui::BoxContent> ProgramsListBox(
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer);
} // namespace Info::BotStarRef::Join } // namespace Info::BotStarRef::Join

View file

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "info/bot/starref/info_bot_starref_common.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/profile/info_profile_icon.h"
#include "info/info_controller.h" #include "info/info_controller.h"
#include "info/info_memento.h" #include "info/info_memento.h"
@ -554,7 +555,8 @@ void InnerWidget::setupViewExisting() {
tr::lng_star_ref_existing_title(), tr::lng_star_ref_existing_title(),
tr::lng_star_ref_existing_about()); tr::lng_star_ref_existing_about());
button->setClickedCallback([=] { button->setClickedCallback([=] {
_controller->showToast(u"List or smth.."_q); const auto window = _controller->parentController();
window->show(Join::ProgramsListBox(window, peer()));
}); });
Ui::AddSkip(_container); Ui::AddSkip(_container);