Added support of some backend limitations for giveaways.

This commit is contained in:
23rd 2023-11-01 05:09:19 +03:00 committed by John Preston
parent 2b1a46356a
commit 2b4047b20d
7 changed files with 96 additions and 29 deletions

View file

@ -2114,6 +2114,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_giveaway_maximum_countries_error#other" = "You can select maximum {count} countries.";
"lng_giveaway_maximum_channels_error#one" = "You can select maximum {count} channel.";
"lng_giveaway_maximum_channels_error#other" = "You can select maximum {count} channels.";
"lng_giveaway_maximum_users_error#one" = "You can select maximum {count} user.";
"lng_giveaway_maximum_users_error#other" = "You can select maximum {count} users.";
"lng_giveaway_channels_confirm_title" = "Channel is Private";
"lng_giveaway_channels_confirm_about" = "Are you sure you want to add a private channel? Users won't be able to join it without an invite link.";

View file

@ -435,18 +435,38 @@ Data::SubscriptionOptions PremiumGiftCodeOptions::options(int amount) {
}
}
[[nodiscard]] int PremiumGiftCodeOptions::giveawayBoostsPerPremium() const {
int PremiumGiftCodeOptions::giveawayBoostsPerPremium() const {
constexpr auto kFallbackCount = 4;
return _peer->session().account().appConfig().get<int>(
u"giveaway_boosts_per_premium"_q,
kFallbackCount);
}
[[nodiscard]] int PremiumGiftCodeOptions::giveawayCountriesMax() const {
int PremiumGiftCodeOptions::giveawayCountriesMax() const {
constexpr auto kFallbackCount = 10;
return _peer->session().account().appConfig().get<int>(
u"giveaway_countries_max"_q,
kFallbackCount);
}
int PremiumGiftCodeOptions::giveawayAddPeersMax() const {
constexpr auto kFallbackCount = 10;
return _peer->session().account().appConfig().get<int>(
u"giveaway_add_peers_max"_q,
kFallbackCount);
}
int PremiumGiftCodeOptions::giveawayPeriodMax() const {
constexpr auto kFallbackCount = 3600 * 24 * 7;
return _peer->session().account().appConfig().get<int>(
u"giveaway_period_max"_q,
kFallbackCount);
}
bool PremiumGiftCodeOptions::giveawayGiftsPurchaseAvailable() const {
return _peer->session().account().appConfig().get<bool>(
u"giveaway_gifts_purchase_available"_q,
false);
}
} // namespace Api

View file

@ -158,6 +158,9 @@ public:
[[nodiscard]] int giveawayBoostsPerPremium() const;
[[nodiscard]] int giveawayCountriesMax() const;
[[nodiscard]] int giveawayAddPeersMax() const;
[[nodiscard]] int giveawayPeriodMax() const;
[[nodiscard]] bool giveawayGiftsPurchaseAvailable() const;
private:
struct Token final {

View file

@ -51,6 +51,18 @@ namespace {
return dateNow;
}
[[nodiscard]] Fn<bool(int)> CreateErrorCallback(
int max,
tr::phrase<lngtag_count> phrase) {
return [=](int count) {
const auto error = (count >= max);
if (error) {
Ui::Toast::Show(phrase(tr::now, lt_count, max));
}
return error;
};
}
} // namespace
void CreateGiveawayBox(
@ -188,11 +200,16 @@ void CreateGiveawayBox(
}, peersBox->lifetime());
};
using Controller = Giveaway::AwardMembersListController;
auto listController = std::make_unique<Controller>(
controller,
peer);
listController->setCheckError(CreateErrorCallback(
state->apiOptions.giveawayAddPeersMax(),
tr::lng_giveaway_maximum_users_error));
box->uiShow()->showBox(
Box<PeerListBox>(
std::make_unique<Giveaway::AwardMembersListController>(
controller,
peer),
std::move(listController),
std::move(initBox)),
Ui::LayerOption::KeepOther);
});
@ -349,13 +366,16 @@ void CreateGiveawayBox(
});
};
using Controller = Giveaway::MyChannelsListController;
auto controller = std::make_unique<Controller>(
peer,
box->uiShow(),
state->selectedToSubscribe);
controller->setCheckError(CreateErrorCallback(
state->apiOptions.giveawayAddPeersMax(),
tr::lng_giveaway_maximum_channels_error));
box->uiShow()->showBox(
Box<PeerListBox>(
std::make_unique<Giveaway::MyChannelsListController>(
peer,
box->uiShow(),
state->selectedToSubscribe),
std::move(initBox)),
Box<PeerListBox>(std::move(controller), std::move(initBox)),
Ui::LayerOption::KeepOther);
});
@ -394,18 +414,9 @@ void CreateGiveawayBox(
auto done = [=](std::vector<QString> list) {
state->countriesValue = std::move(list);
};
auto error = [=](int count) {
const auto max = state->apiOptions.giveawayCountriesMax();
const auto error = (count >= max);
if (error) {
Ui::Toast::Show(tr::lng_giveaway_maximum_countries_error(
tr::now,
lt_count,
max));
}
return error;
};
auto error = CreateErrorCallback(
state->apiOptions.giveawayCountriesMax(),
tr::lng_giveaway_maximum_countries_error);
box->uiShow()->showBox(Box(
Ui::SelectCountriesBox,
state->countriesValue.current(),
@ -469,7 +480,6 @@ void CreateGiveawayBox(
st::defaultSettingsButton);
button->setClickedCallback([=] {
constexpr auto kSevenDays = 3600 * 24 * 7;
box->uiShow()->showBox(Box([=](not_null<Ui::GenericBox*> b) {
Ui::ChooseDateTimeBox(b, {
.title = tr::lng_giveaway_date_select(),
@ -482,7 +492,7 @@ void CreateGiveawayBox(
.time = state->dateValue.current(),
.max = [=] {
return QDateTime::currentSecsSinceEpoch()
+ kSevenDays;
+ state->apiOptions.giveawayPeriodMax();;
},
});
}));

View file

@ -112,7 +112,13 @@ AwardMembersListController::AwardMembersListController(
}
void AwardMembersListController::rowClicked(not_null<PeerListRow*> row) {
delegate()->peerListSetRowChecked(row, !row->checked());
const auto checked = !row->checked();
if (checked
&& _checkErrorCallback
&& _checkErrorCallback(delegate()->peerListSelectedRowsCount())) {
return;
}
delegate()->peerListSetRowChecked(row, checked);
}
std::unique_ptr<PeerListRow> AwardMembersListController::createRow(
@ -130,6 +136,10 @@ base::unique_qptr<Ui::PopupMenu> AwardMembersListController::rowContextMenu(
return nullptr;
}
void AwardMembersListController::setCheckError(Fn<bool(int)> callback) {
_checkErrorCallback = std::move(callback);
}
MyChannelsListController::MyChannelsListController(
not_null<PeerData*> peer,
std::shared_ptr<Ui::Show> show,
@ -160,6 +170,11 @@ std::unique_ptr<PeerListRow> MyChannelsListController::createRestoredRow(
void MyChannelsListController::rowClicked(not_null<PeerListRow*> row) {
const auto channel = row->peer()->asChannel();
const auto checked = !row->checked();
if (checked
&& _checkErrorCallback
&& _checkErrorCallback(delegate()->peerListSelectedRowsCount())) {
return;
}
if (checked && channel && channel->username().isEmpty()) {
_show->showBox(Box(Ui::ConfirmBox, Ui::ConfirmBoxArgs{
.text = tr::lng_giveaway_channels_confirm_about(),
@ -224,6 +239,10 @@ void MyChannelsListController::prepare() {
}).send();
}
void MyChannelsListController::setCheckError(Fn<bool(int)> callback) {
_checkErrorCallback = std::move(callback);
}
std::unique_ptr<PeerListRow> MyChannelsListController::createRow(
not_null<ChannelData*> channel) const {
if (channel->isMegagroup()) {

View file

@ -29,6 +29,8 @@ public:
not_null<Window::SessionNavigation*> navigation,
not_null<PeerData*> peer);
void setCheckError(Fn<bool(int)> callback);
void rowClicked(not_null<PeerListRow*> row) override;
std::unique_ptr<PeerListRow> createRow(
not_null<PeerData*> participant) const override;
@ -36,6 +38,9 @@ public:
QWidget *parent,
not_null<PeerListRow*> row) override;
private:
Fn<bool(int)> _checkErrorCallback;
};
class MyChannelsListController : public PeerListController {
@ -45,6 +50,8 @@ public:
std::shared_ptr<Ui::Show> show,
std::vector<not_null<PeerData*>> selected);
void setCheckError(Fn<bool(int)> callback);
Main::Session &session() const override;
void prepare() override;
void rowClicked(not_null<PeerListRow*> row) override;
@ -61,6 +68,8 @@ private:
const not_null<PeerData*> _peer;
const std::shared_ptr<Ui::Show> _show;
Fn<bool(int)> _checkErrorCallback;
std::vector<not_null<PeerData*>> _selected;
rpl::lifetime _apiLifetime;

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "info/boosts/info_boosts_inner_widget.h"
#include "api/api_premium.h"
#include "api/api_statistics.h"
#include "boxes/peers/edit_peer_invite_link.h"
#include "info/boosts/create_giveaway_box.h"
@ -182,6 +183,10 @@ void FillGetBoostsButton(
not_null<Controller*> controller,
std::shared_ptr<Ui::Show> show,
not_null<PeerData*> peer) {
if (!Api::PremiumGiftCodeOptions(peer).giveawayGiftsPurchaseAvailable()) {
return;
}
::Settings::AddSkip(content);
const auto &st = st::getBoostsButton;
const auto &icon = st::getBoostsButtonIcon;
const auto button = content->add(
@ -199,6 +204,8 @@ void FillGetBoostsButton(
st::infoSharedMediaButtonIconPosition.x(),
(st.height + rect::m::sum::v(st.padding) - icon.height()) / 2,
})->show();
::Settings::AddSkip(content);
::Settings::AddDividerText(content, tr::lng_boosts_get_boosts_subtext());
}
} // namespace
@ -293,10 +300,7 @@ void InnerWidget::fill() {
::Settings::AddSkip(inner);
::Settings::AddDividerText(inner, tr::lng_boosts_link_subtext());
::Settings::AddSkip(inner);
FillGetBoostsButton(inner, _controller, _show, _peer);
::Settings::AddSkip(inner);
::Settings::AddDividerText(inner, tr::lng_boosts_get_boosts_subtext());
resizeToWidth(width());
crl::on_main([=]{ fakeShowed->fire({}); });