mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added ability to filter users by countries for giveaway to giveaway box.
This commit is contained in:
parent
2d097ca9ae
commit
fc6d4d66b7
6 changed files with 127 additions and 12 deletions
|
@ -2089,8 +2089,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_giveaway_channels_about" = "Choose the channels the users need to join to take part in the giveaway.";
|
"lng_giveaway_channels_about" = "Choose the channels the users need to join to take part in the giveaway.";
|
||||||
"lng_giveaway_users_title" = "Users eligible for the giveaway";
|
"lng_giveaway_users_title" = "Users eligible for the giveaway";
|
||||||
"lng_giveaway_users_all" = "All subscribers";
|
"lng_giveaway_users_all" = "All subscribers";
|
||||||
|
"lng_giveaway_users_from_all_countries" = "from all countries";
|
||||||
|
"lng_giveaway_users_from_one_country" = "from {country}";
|
||||||
|
"lng_giveaway_users_from_countries#one" = "from {count} country";
|
||||||
|
"lng_giveaway_users_from_countries#other" = "from {count} countries";
|
||||||
"lng_giveaway_users_new" = "Only new subscribers";
|
"lng_giveaway_users_new" = "Only new subscribers";
|
||||||
"lng_giveaway_users_about" = "Choose if you want to limit the giveaway only to the newly joined subscribers.";
|
"lng_giveaway_users_about" = "Choose if you want to limit the giveaway only to those who joined the channel after the giveaway started or to users from specific countries.";
|
||||||
"lng_giveaway_start" = "Start Giveaway";
|
"lng_giveaway_start" = "Start Giveaway";
|
||||||
"lng_giveaway_award" = "Gift Premium";
|
"lng_giveaway_award" = "Gift Premium";
|
||||||
"lng_giveaway_date_title" = "Date when giveaway ends";
|
"lng_giveaway_date_title" = "Date when giveaway ends";
|
||||||
|
@ -2106,6 +2110,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_giveaway_channels_select#other" = "Select up to {count} channels";
|
"lng_giveaway_channels_select#other" = "Select up to {count} channels";
|
||||||
"lng_giveaway_recipients_save" = "Save Recipients";
|
"lng_giveaway_recipients_save" = "Save Recipients";
|
||||||
"lng_giveaway_recipients_deselect" = "Deselect All";
|
"lng_giveaway_recipients_deselect" = "Deselect All";
|
||||||
|
"lng_giveaway_maximum_countries_error#one" = "You can select maximum {count} country.";
|
||||||
|
"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_prize_title" = "Congratulations!";
|
"lng_prize_title" = "Congratulations!";
|
||||||
"lng_prize_about" = "You won a prize in a giveaway organized by {channel}.";
|
"lng_prize_about" = "You won a prize in a giveaway organized by {channel}.";
|
||||||
|
|
|
@ -442,4 +442,11 @@ Data::SubscriptionOptions PremiumGiftCodeOptions::options(int amount) {
|
||||||
kFallbackCount);
|
kFallbackCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] int PremiumGiftCodeOptions::giveawayCountriesMax() const {
|
||||||
|
constexpr auto kFallbackCount = 10;
|
||||||
|
return _peer->session().account().appConfig().get<int>(
|
||||||
|
u"giveaway_countries_max"_q,
|
||||||
|
kFallbackCount);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Api
|
} // namespace Api
|
||||||
|
|
|
@ -157,6 +157,7 @@ public:
|
||||||
int monthsIndex);
|
int monthsIndex);
|
||||||
|
|
||||||
[[nodiscard]] int giveawayBoostsPerPremium() const;
|
[[nodiscard]] int giveawayBoostsPerPremium() const;
|
||||||
|
[[nodiscard]] int giveawayCountriesMax() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Token final {
|
struct Token final {
|
||||||
|
|
|
@ -8,12 +8,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "info/boosts/create_giveaway_box.h"
|
#include "info/boosts/create_giveaway_box.h"
|
||||||
|
|
||||||
#include "api/api_premium.h"
|
#include "api/api_premium.h"
|
||||||
|
#include "base/call_delayed.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "boxes/peers/edit_participants_box.h" // ParticipantsBoxController
|
#include "boxes/peers/edit_participants_box.h" // ParticipantsBoxController
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_subscription_option.h"
|
#include "data/data_subscription_option.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "info/boosts/giveaway/giveaway_type_row.h"
|
#include "info/boosts/giveaway/giveaway_type_row.h"
|
||||||
|
#include "info/boosts/giveaway/select_countries_box.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "payments/payments_checkout_process.h" // Payments::CheckoutProcess
|
#include "payments/payments_checkout_process.h" // Payments::CheckoutProcess
|
||||||
|
@ -25,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/layers/generic_box.h"
|
#include "ui/layers/generic_box.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/widgets/checkbox.h"
|
#include "ui/widgets/checkbox.h"
|
||||||
#include "ui/widgets/continuous_sliders.h"
|
#include "ui/widgets/continuous_sliders.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
|
@ -99,6 +102,7 @@ void CreateGiveawayBox(
|
||||||
rpl::variable<GiveawayType> typeValue;
|
rpl::variable<GiveawayType> typeValue;
|
||||||
rpl::variable<int> sliderValue;
|
rpl::variable<int> sliderValue;
|
||||||
rpl::variable<TimeId> dateValue;
|
rpl::variable<TimeId> dateValue;
|
||||||
|
rpl::variable<std::vector<QString>> countriesValue;
|
||||||
|
|
||||||
bool confirmButtonBusy = false;
|
bool confirmButtonBusy = false;
|
||||||
};
|
};
|
||||||
|
@ -308,6 +312,90 @@ void CreateGiveawayBox(
|
||||||
Settings::AddSkip(dateContainer);
|
Settings::AddSkip(dateContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto membersGroup = std::make_shared<GiveawayGroup>();
|
||||||
|
{
|
||||||
|
const auto countriesContainer = randomWrap->entity()->add(
|
||||||
|
object_ptr<Ui::VerticalLayout>(randomWrap));
|
||||||
|
Settings::AddSubsectionTitle(
|
||||||
|
countriesContainer,
|
||||||
|
tr::lng_giveaway_users_title());
|
||||||
|
|
||||||
|
membersGroup->setValue(GiveawayType::AllMembers);
|
||||||
|
auto subtitle = state->countriesValue.value(
|
||||||
|
) | rpl::map([=](const std::vector<QString> &list) {
|
||||||
|
return list.empty()
|
||||||
|
? tr::lng_giveaway_users_from_all_countries()
|
||||||
|
: (list.size() == 1)
|
||||||
|
? tr::lng_giveaway_users_from_one_country(
|
||||||
|
lt_country,
|
||||||
|
rpl::single(Countries::Instance().countryNameByISO2(
|
||||||
|
list.front())))
|
||||||
|
: tr::lng_giveaway_users_from_countries(
|
||||||
|
lt_count,
|
||||||
|
rpl::single(list.size()) | tr::to_count());
|
||||||
|
}) | rpl::flatten_latest();
|
||||||
|
|
||||||
|
const auto showBox = [=] {
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
box->uiShow()->showBox(Box(
|
||||||
|
Ui::SelectCountriesBox,
|
||||||
|
state->countriesValue.current(),
|
||||||
|
std::move(done),
|
||||||
|
std::move(error)));
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto createCallback = [=](GiveawayType type) {
|
||||||
|
return [=] {
|
||||||
|
const auto was = membersGroup->value();
|
||||||
|
membersGroup->setValue(type);
|
||||||
|
const auto now = membersGroup->value();
|
||||||
|
if (was == now) {
|
||||||
|
base::call_delayed(
|
||||||
|
st::defaultRippleAnimation.hideDuration,
|
||||||
|
box,
|
||||||
|
showBox);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto row = countriesContainer->add(
|
||||||
|
object_ptr<Giveaway::GiveawayTypeRow>(
|
||||||
|
box,
|
||||||
|
GiveawayType::AllMembers,
|
||||||
|
rpl::duplicate(subtitle)));
|
||||||
|
row->addRadio(membersGroup);
|
||||||
|
row->setClickedCallback(createCallback(GiveawayType::AllMembers));
|
||||||
|
}
|
||||||
|
const auto row = countriesContainer->add(
|
||||||
|
object_ptr<Giveaway::GiveawayTypeRow>(
|
||||||
|
box,
|
||||||
|
GiveawayType::OnlyNewMembers,
|
||||||
|
std::move(subtitle)));
|
||||||
|
row->addRadio(membersGroup);
|
||||||
|
row->setClickedCallback(createCallback(GiveawayType::OnlyNewMembers));
|
||||||
|
|
||||||
|
Settings::AddSkip(countriesContainer);
|
||||||
|
Settings::AddDividerText(
|
||||||
|
countriesContainer,
|
||||||
|
tr::lng_giveaway_users_about());
|
||||||
|
Settings::AddSkip(countriesContainer);
|
||||||
|
}
|
||||||
|
|
||||||
const auto durationGroup = std::make_shared<Ui::RadiobuttonGroup>(0);
|
const auto durationGroup = std::make_shared<Ui::RadiobuttonGroup>(0);
|
||||||
{
|
{
|
||||||
const auto listOptions = box->verticalLayout()->add(
|
const auto listOptions = box->verticalLayout()->add(
|
||||||
|
|
|
@ -25,8 +25,10 @@ GiveawayTypeRow::GiveawayTypeRow(
|
||||||
Type type,
|
Type type,
|
||||||
rpl::producer<QString> subtitle)
|
rpl::producer<QString> subtitle)
|
||||||
: RippleButton(parent, st::defaultRippleAnimation)
|
: RippleButton(parent, st::defaultRippleAnimation)
|
||||||
, _st(st::giveawayTypeListItem)
|
|
||||||
, _type(type)
|
, _type(type)
|
||||||
|
, _st((_type == Type::SpecificUsers || _type == Type::Random)
|
||||||
|
? st::giveawayTypeListItem
|
||||||
|
: st::defaultPeerListItem)
|
||||||
, _userpic(
|
, _userpic(
|
||||||
Ui::EmptyUserpic::UserpicColor((_type == Type::SpecificUsers)
|
Ui::EmptyUserpic::UserpicColor((_type == Type::SpecificUsers)
|
||||||
? kColorIndexSpecific
|
? kColorIndexSpecific
|
||||||
|
@ -36,7 +38,11 @@ GiveawayTypeRow::GiveawayTypeRow(
|
||||||
_st.nameStyle,
|
_st.nameStyle,
|
||||||
(type == Type::SpecificUsers)
|
(type == Type::SpecificUsers)
|
||||||
? tr::lng_giveaway_award_option(tr::now)
|
? tr::lng_giveaway_award_option(tr::now)
|
||||||
: tr::lng_giveaway_create_option(tr::now),
|
: (type == Type::Random)
|
||||||
|
? tr::lng_giveaway_create_option(tr::now)
|
||||||
|
: (type == Type::AllMembers)
|
||||||
|
? tr::lng_giveaway_users_all(tr::now)
|
||||||
|
: tr::lng_giveaway_users_new(tr::now),
|
||||||
Ui::NameTextOptions()) {
|
Ui::NameTextOptions()) {
|
||||||
std::move(
|
std::move(
|
||||||
subtitle
|
subtitle
|
||||||
|
@ -56,18 +62,20 @@ void GiveawayTypeRow::paintEvent(QPaintEvent *e) {
|
||||||
const auto skipRight = _st.photoPosition.x();
|
const auto skipRight = _st.photoPosition.x();
|
||||||
const auto outerWidth = width();
|
const auto outerWidth = width();
|
||||||
const auto isSpecific = (_type == Type::SpecificUsers);
|
const auto isSpecific = (_type == Type::SpecificUsers);
|
||||||
|
const auto hasUserpic = (_type == Type::Random) || isSpecific;
|
||||||
|
|
||||||
if (paintOver) {
|
if (paintOver) {
|
||||||
p.fillRect(e->rect(), _st.button.textBgOver);
|
p.fillRect(e->rect(), _st.button.textBgOver);
|
||||||
}
|
}
|
||||||
Ui::RippleButton::paintRipple(p, 0, 0);
|
Ui::RippleButton::paintRipple(p, 0, 0);
|
||||||
_userpic.paintCircle(
|
if (hasUserpic) {
|
||||||
p,
|
_userpic.paintCircle(
|
||||||
_st.photoPosition.x(),
|
p,
|
||||||
_st.photoPosition.y(),
|
_st.photoPosition.x(),
|
||||||
outerWidth,
|
_st.photoPosition.y(),
|
||||||
_st.photoSize);
|
outerWidth,
|
||||||
{
|
_st.photoSize);
|
||||||
|
|
||||||
const auto &userpic = isSpecific
|
const auto &userpic = isSpecific
|
||||||
? st::giveawayUserpicGroup
|
? st::giveawayUserpicGroup
|
||||||
: st::giveawayUserpic;
|
: st::giveawayUserpic;
|
||||||
|
@ -91,7 +99,7 @@ void GiveawayTypeRow::paintEvent(QPaintEvent *e) {
|
||||||
const auto statusy = _st.statusPosition.y();
|
const auto statusy = _st.statusPosition.y();
|
||||||
const auto statusw = outerWidth - statusx - skipRight;
|
const auto statusw = outerWidth - statusx - skipRight;
|
||||||
p.setFont(st::contactsStatusFont);
|
p.setFont(st::contactsStatusFont);
|
||||||
p.setPen(isSpecific ? st::lightButtonFg : _st.statusFg);
|
p.setPen((isSpecific || !hasUserpic) ? st::lightButtonFg : _st.statusFg);
|
||||||
_status.drawLeftElided(p, statusx, statusy, statusw, outerWidth);
|
_status.drawLeftElided(p, statusx, statusy, statusw, outerWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,9 @@ public:
|
||||||
enum class Type {
|
enum class Type {
|
||||||
Random,
|
Random,
|
||||||
SpecificUsers,
|
SpecificUsers,
|
||||||
|
|
||||||
|
AllMembers,
|
||||||
|
OnlyNewMembers,
|
||||||
};
|
};
|
||||||
|
|
||||||
GiveawayTypeRow(
|
GiveawayTypeRow(
|
||||||
|
@ -37,8 +40,8 @@ protected:
|
||||||
int resizeGetHeight(int) override;
|
int resizeGetHeight(int) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const style::PeerListItem _st;
|
|
||||||
const Type _type;
|
const Type _type;
|
||||||
|
const style::PeerListItem _st;
|
||||||
|
|
||||||
Ui::EmptyUserpic _userpic;
|
Ui::EmptyUserpic _userpic;
|
||||||
Ui::Text::String _status;
|
Ui::Text::String _status;
|
||||||
|
|
Loading…
Add table
Reference in a new issue