mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added support of some backend limitations for giveaways.
This commit is contained in:
parent
2b1a46356a
commit
2b4047b20d
7 changed files with 96 additions and 29 deletions
|
@ -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_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#one" = "You can select maximum {count} channel.";
|
||||||
"lng_giveaway_maximum_channels_error#other" = "You can select maximum {count} channels.";
|
"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_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.";
|
"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.";
|
||||||
|
|
||||||
|
|
|
@ -435,18 +435,38 @@ Data::SubscriptionOptions PremiumGiftCodeOptions::options(int amount) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] int PremiumGiftCodeOptions::giveawayBoostsPerPremium() const {
|
int PremiumGiftCodeOptions::giveawayBoostsPerPremium() const {
|
||||||
constexpr auto kFallbackCount = 4;
|
constexpr auto kFallbackCount = 4;
|
||||||
return _peer->session().account().appConfig().get<int>(
|
return _peer->session().account().appConfig().get<int>(
|
||||||
u"giveaway_boosts_per_premium"_q,
|
u"giveaway_boosts_per_premium"_q,
|
||||||
kFallbackCount);
|
kFallbackCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] int PremiumGiftCodeOptions::giveawayCountriesMax() const {
|
int PremiumGiftCodeOptions::giveawayCountriesMax() const {
|
||||||
constexpr auto kFallbackCount = 10;
|
constexpr auto kFallbackCount = 10;
|
||||||
return _peer->session().account().appConfig().get<int>(
|
return _peer->session().account().appConfig().get<int>(
|
||||||
u"giveaway_countries_max"_q,
|
u"giveaway_countries_max"_q,
|
||||||
kFallbackCount);
|
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
|
} // namespace Api
|
||||||
|
|
|
@ -158,6 +158,9 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] int giveawayBoostsPerPremium() const;
|
[[nodiscard]] int giveawayBoostsPerPremium() const;
|
||||||
[[nodiscard]] int giveawayCountriesMax() const;
|
[[nodiscard]] int giveawayCountriesMax() const;
|
||||||
|
[[nodiscard]] int giveawayAddPeersMax() const;
|
||||||
|
[[nodiscard]] int giveawayPeriodMax() const;
|
||||||
|
[[nodiscard]] bool giveawayGiftsPurchaseAvailable() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Token final {
|
struct Token final {
|
||||||
|
|
|
@ -51,6 +51,18 @@ namespace {
|
||||||
return dateNow;
|
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
|
} // namespace
|
||||||
|
|
||||||
void CreateGiveawayBox(
|
void CreateGiveawayBox(
|
||||||
|
@ -188,11 +200,16 @@ void CreateGiveawayBox(
|
||||||
}, peersBox->lifetime());
|
}, 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->uiShow()->showBox(
|
||||||
Box<PeerListBox>(
|
Box<PeerListBox>(
|
||||||
std::make_unique<Giveaway::AwardMembersListController>(
|
std::move(listController),
|
||||||
controller,
|
|
||||||
peer),
|
|
||||||
std::move(initBox)),
|
std::move(initBox)),
|
||||||
Ui::LayerOption::KeepOther);
|
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->uiShow()->showBox(
|
||||||
Box<PeerListBox>(
|
Box<PeerListBox>(std::move(controller), std::move(initBox)),
|
||||||
std::make_unique<Giveaway::MyChannelsListController>(
|
|
||||||
peer,
|
|
||||||
box->uiShow(),
|
|
||||||
state->selectedToSubscribe),
|
|
||||||
std::move(initBox)),
|
|
||||||
Ui::LayerOption::KeepOther);
|
Ui::LayerOption::KeepOther);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -394,18 +414,9 @@ void CreateGiveawayBox(
|
||||||
auto done = [=](std::vector<QString> list) {
|
auto done = [=](std::vector<QString> list) {
|
||||||
state->countriesValue = std::move(list);
|
state->countriesValue = std::move(list);
|
||||||
};
|
};
|
||||||
auto error = [=](int count) {
|
auto error = CreateErrorCallback(
|
||||||
const auto max = state->apiOptions.giveawayCountriesMax();
|
state->apiOptions.giveawayCountriesMax(),
|
||||||
const auto error = (count >= max);
|
tr::lng_giveaway_maximum_countries_error);
|
||||||
if (error) {
|
|
||||||
Ui::Toast::Show(tr::lng_giveaway_maximum_countries_error(
|
|
||||||
tr::now,
|
|
||||||
lt_count,
|
|
||||||
max));
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
};
|
|
||||||
|
|
||||||
box->uiShow()->showBox(Box(
|
box->uiShow()->showBox(Box(
|
||||||
Ui::SelectCountriesBox,
|
Ui::SelectCountriesBox,
|
||||||
state->countriesValue.current(),
|
state->countriesValue.current(),
|
||||||
|
@ -469,7 +480,6 @@ void CreateGiveawayBox(
|
||||||
st::defaultSettingsButton);
|
st::defaultSettingsButton);
|
||||||
|
|
||||||
button->setClickedCallback([=] {
|
button->setClickedCallback([=] {
|
||||||
constexpr auto kSevenDays = 3600 * 24 * 7;
|
|
||||||
box->uiShow()->showBox(Box([=](not_null<Ui::GenericBox*> b) {
|
box->uiShow()->showBox(Box([=](not_null<Ui::GenericBox*> b) {
|
||||||
Ui::ChooseDateTimeBox(b, {
|
Ui::ChooseDateTimeBox(b, {
|
||||||
.title = tr::lng_giveaway_date_select(),
|
.title = tr::lng_giveaway_date_select(),
|
||||||
|
@ -482,7 +492,7 @@ void CreateGiveawayBox(
|
||||||
.time = state->dateValue.current(),
|
.time = state->dateValue.current(),
|
||||||
.max = [=] {
|
.max = [=] {
|
||||||
return QDateTime::currentSecsSinceEpoch()
|
return QDateTime::currentSecsSinceEpoch()
|
||||||
+ kSevenDays;
|
+ state->apiOptions.giveawayPeriodMax();;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -112,7 +112,13 @@ AwardMembersListController::AwardMembersListController(
|
||||||
}
|
}
|
||||||
|
|
||||||
void AwardMembersListController::rowClicked(not_null<PeerListRow*> row) {
|
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(
|
std::unique_ptr<PeerListRow> AwardMembersListController::createRow(
|
||||||
|
@ -130,6 +136,10 @@ base::unique_qptr<Ui::PopupMenu> AwardMembersListController::rowContextMenu(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AwardMembersListController::setCheckError(Fn<bool(int)> callback) {
|
||||||
|
_checkErrorCallback = std::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
MyChannelsListController::MyChannelsListController(
|
MyChannelsListController::MyChannelsListController(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
std::shared_ptr<Ui::Show> show,
|
std::shared_ptr<Ui::Show> show,
|
||||||
|
@ -160,6 +170,11 @@ std::unique_ptr<PeerListRow> MyChannelsListController::createRestoredRow(
|
||||||
void MyChannelsListController::rowClicked(not_null<PeerListRow*> row) {
|
void MyChannelsListController::rowClicked(not_null<PeerListRow*> row) {
|
||||||
const auto channel = row->peer()->asChannel();
|
const auto channel = row->peer()->asChannel();
|
||||||
const auto checked = !row->checked();
|
const auto checked = !row->checked();
|
||||||
|
if (checked
|
||||||
|
&& _checkErrorCallback
|
||||||
|
&& _checkErrorCallback(delegate()->peerListSelectedRowsCount())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (checked && channel && channel->username().isEmpty()) {
|
if (checked && channel && channel->username().isEmpty()) {
|
||||||
_show->showBox(Box(Ui::ConfirmBox, Ui::ConfirmBoxArgs{
|
_show->showBox(Box(Ui::ConfirmBox, Ui::ConfirmBoxArgs{
|
||||||
.text = tr::lng_giveaway_channels_confirm_about(),
|
.text = tr::lng_giveaway_channels_confirm_about(),
|
||||||
|
@ -224,6 +239,10 @@ void MyChannelsListController::prepare() {
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyChannelsListController::setCheckError(Fn<bool(int)> callback) {
|
||||||
|
_checkErrorCallback = std::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<PeerListRow> MyChannelsListController::createRow(
|
std::unique_ptr<PeerListRow> MyChannelsListController::createRow(
|
||||||
not_null<ChannelData*> channel) const {
|
not_null<ChannelData*> channel) const {
|
||||||
if (channel->isMegagroup()) {
|
if (channel->isMegagroup()) {
|
||||||
|
|
|
@ -29,6 +29,8 @@ public:
|
||||||
not_null<Window::SessionNavigation*> navigation,
|
not_null<Window::SessionNavigation*> navigation,
|
||||||
not_null<PeerData*> peer);
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
|
void setCheckError(Fn<bool(int)> callback);
|
||||||
|
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
std::unique_ptr<PeerListRow> createRow(
|
std::unique_ptr<PeerListRow> createRow(
|
||||||
not_null<PeerData*> participant) const override;
|
not_null<PeerData*> participant) const override;
|
||||||
|
@ -36,6 +38,9 @@ public:
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<PeerListRow*> row) override;
|
not_null<PeerListRow*> row) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Fn<bool(int)> _checkErrorCallback;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MyChannelsListController : public PeerListController {
|
class MyChannelsListController : public PeerListController {
|
||||||
|
@ -45,6 +50,8 @@ public:
|
||||||
std::shared_ptr<Ui::Show> show,
|
std::shared_ptr<Ui::Show> show,
|
||||||
std::vector<not_null<PeerData*>> selected);
|
std::vector<not_null<PeerData*>> selected);
|
||||||
|
|
||||||
|
void setCheckError(Fn<bool(int)> callback);
|
||||||
|
|
||||||
Main::Session &session() const override;
|
Main::Session &session() const override;
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
|
@ -61,6 +68,8 @@ private:
|
||||||
const not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
const std::shared_ptr<Ui::Show> _show;
|
const std::shared_ptr<Ui::Show> _show;
|
||||||
|
|
||||||
|
Fn<bool(int)> _checkErrorCallback;
|
||||||
|
|
||||||
std::vector<not_null<PeerData*>> _selected;
|
std::vector<not_null<PeerData*>> _selected;
|
||||||
|
|
||||||
rpl::lifetime _apiLifetime;
|
rpl::lifetime _apiLifetime;
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "info/boosts/info_boosts_inner_widget.h"
|
#include "info/boosts/info_boosts_inner_widget.h"
|
||||||
|
|
||||||
|
#include "api/api_premium.h"
|
||||||
#include "api/api_statistics.h"
|
#include "api/api_statistics.h"
|
||||||
#include "boxes/peers/edit_peer_invite_link.h"
|
#include "boxes/peers/edit_peer_invite_link.h"
|
||||||
#include "info/boosts/create_giveaway_box.h"
|
#include "info/boosts/create_giveaway_box.h"
|
||||||
|
@ -182,6 +183,10 @@ void FillGetBoostsButton(
|
||||||
not_null<Controller*> controller,
|
not_null<Controller*> controller,
|
||||||
std::shared_ptr<Ui::Show> show,
|
std::shared_ptr<Ui::Show> show,
|
||||||
not_null<PeerData*> peer) {
|
not_null<PeerData*> peer) {
|
||||||
|
if (!Api::PremiumGiftCodeOptions(peer).giveawayGiftsPurchaseAvailable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
::Settings::AddSkip(content);
|
||||||
const auto &st = st::getBoostsButton;
|
const auto &st = st::getBoostsButton;
|
||||||
const auto &icon = st::getBoostsButtonIcon;
|
const auto &icon = st::getBoostsButtonIcon;
|
||||||
const auto button = content->add(
|
const auto button = content->add(
|
||||||
|
@ -199,6 +204,8 @@ void FillGetBoostsButton(
|
||||||
st::infoSharedMediaButtonIconPosition.x(),
|
st::infoSharedMediaButtonIconPosition.x(),
|
||||||
(st.height + rect::m::sum::v(st.padding) - icon.height()) / 2,
|
(st.height + rect::m::sum::v(st.padding) - icon.height()) / 2,
|
||||||
})->show();
|
})->show();
|
||||||
|
::Settings::AddSkip(content);
|
||||||
|
::Settings::AddDividerText(content, tr::lng_boosts_get_boosts_subtext());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -293,10 +300,7 @@ void InnerWidget::fill() {
|
||||||
::Settings::AddSkip(inner);
|
::Settings::AddSkip(inner);
|
||||||
::Settings::AddDividerText(inner, tr::lng_boosts_link_subtext());
|
::Settings::AddDividerText(inner, tr::lng_boosts_link_subtext());
|
||||||
|
|
||||||
::Settings::AddSkip(inner);
|
|
||||||
FillGetBoostsButton(inner, _controller, _show, _peer);
|
FillGetBoostsButton(inner, _controller, _show, _peer);
|
||||||
::Settings::AddSkip(inner);
|
|
||||||
::Settings::AddDividerText(inner, tr::lng_boosts_get_boosts_subtext());
|
|
||||||
|
|
||||||
resizeToWidth(width());
|
resizeToWidth(width());
|
||||||
crl::on_main([=]{ fakeShowed->fire({}); });
|
crl::on_main([=]{ fakeShowed->fire({}); });
|
||||||
|
|
Loading…
Add table
Reference in a new issue