Allow boosts / giveaways in groups.

This commit is contained in:
John Preston 2024-02-02 21:30:53 +04:00
parent cb174cb0bf
commit f6a8c1e996
16 changed files with 302 additions and 148 deletions

View File

@ -1736,6 +1736,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_story_mention_button" = "View Story";
"lng_action_story_mention_me_unavailable" = "The story where you mentioned {user} is no longer available.";
"lng_action_story_mention_unavailable" = "The story where {user} mentioned you is no longer available.";
"lng_action_giveaway_started_group" = "{from} just started a giveaway of Telegram Premium subscriptions to its members.";
"lng_action_giveaway_started" = "{from} just started a giveaway of Telegram Premium subscriptions to its followers.";
"lng_action_giveaway_results#one" = "{count} winner of the giveaway was randomly selected by Telegram and received private messages with giftcodes.";
"lng_action_giveaway_results#other" = "{count} winners of the giveaway were randomly selected by Telegram and received private messages with giftcodes.";
@ -2150,13 +2151,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_premium_gifts_terms_policy" = "Privacy Policy";
"lng_boost_channel_button" = "Boost Channel";
"lng_boost_group_button" = "Boost Group";
"lng_boost_again_button" = "Boost Again";
"lng_boost_level#one" = "Level {count}";
"lng_boost_level#other" = "Level {count}";
"lng_boost_channel_title_first" = "Enable stories for channel";
"lng_boost_channel_title_first_group" = "Enable stories for group";
"lng_boost_channel_needs_first#one" = "{channel} needs **{count}** more boost to enable posting stories. Help make it possible!";
"lng_boost_channel_needs_first#other" = "{channel} needs **{count}** more boosts to enable posting stories. Help make it possible!";
"lng_boost_channel_title_more" = "Help upgrade channel";
"lng_boost_channel_title_more_group" = "Help upgrade group";
"lng_boost_channel_needs_more#one" = "{channel} needs **{count}** more boost to be able to {post}.";
"lng_boost_channel_needs_more#other" = "{channel} needs **{count}** more boosts to be able to {post}.";
"lng_boost_channel_title_max" = "Maximum level reached";
@ -2168,10 +2172,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_boost_channel_reached_first" = "This channel reached **Level 1** and can now post stories.";
"lng_boost_channel_reached_more#one" = "This channel reached **Level {count}** and can now {post}.";
"lng_boost_channel_reached_more#other" = "This channel reached **Level {count}** and can now {post}.";
"lng_boost_channel_you_first_group#one" = "This group needs **{count}** more boost\nto enable stories.";
"lng_boost_channel_you_first_group#other" = "This group needs **{count}** more boosts\nto enable stories.";
"lng_boost_channel_you_more_group#one" = "This group needs **{count}** more boost\nto be able to {post}.";
"lng_boost_channel_you_more_group#other" = "This group needs **{count}** more boosts\nto be able to {post}.";
"lng_boost_channel_reached_first_group" = "This group reached **Level 1** and can now post stories.";
"lng_boost_channel_reached_more_group#one" = "This group reached **Level {count}** and can now {post}.";
"lng_boost_channel_reached_more_group#other" = "This group reached **Level {count}** and can now {post}.";
"lng_boost_channel_post_stories#one" = "post **{count} story** per day";
"lng_boost_channel_post_stories#other" = "post **{count} stories** per day";
"lng_boost_error_gifted_title" = "Can't boost with gifted Premium!";
"lng_boost_error_gifted_text" = "Because your **Telegram Premium** subscription was gifted to you, you can't use it to boost channels.";
"lng_boost_error_gifted_text_group" = "Because your **Telegram Premium** subscription was gifted to you, you can't use it to boost groups.";
"lng_boost_need_more" = "More boosts needed";
"lng_boost_need_more_text#one" = "To boost {channel}, gift **Telegram Premium** to a friend and get **{count}** boosts.";
"lng_boost_need_more_text#other" = "To boost {channel}, gift **Telegram Premium** to a friend and get **{count}** boosts.";
@ -2179,10 +2191,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_boost_need_more_again#other" = "To boost {channel} again, gift **Telegram Premium** to a friend and get **{count}** additional boosts.";
"lng_boost_error_already_title" = "Already Boosted!";
"lng_boost_error_already_text" = "You are already boosting this channel.";
"lng_boost_error_already_text_group" = "You are already boosting this group.";
"lng_boost_error_premium_title" = "Premium needed!";
"lng_boost_error_premium_text_group" = "Only **Telegram Premium** subscribers can boost groups. Do you want to subscribe to **Telegram Premium**?";
"lng_boost_error_premium_text" = "Only **Telegram Premium** subscribers can boost channels. Do you want to subscribe to **Telegram Premium**?";
"lng_boost_error_premium_yes" = "Yes";
"lng_boost_error_flood_title" = "Can't boost too often!";
"lng_boost_error_flood_text_group" = "You can change the group you boost only once a day. Next time you can boost is in {left}.";
"lng_boost_error_flood_text" = "You can change the channel you boost only once a day. Next time you can boost is in {left}.";
"lng_boost_now_instead" = "You currently boost {channel}. Do you want to boost {other} instead?";
"lng_boost_now_replace" = "Replace";
@ -2224,6 +2239,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_giveaway_new_title" = "Boosts via Gifts";
"lng_giveaway_new_about" = "Get more boosts for your channel by gifting Premium to your subscribers.";
"lng_giveaway_new_about_group" = "Get more boosts for your group by gifting Premium to your subscribers.";
"lng_giveaway_create_option" = "Create Giveaway";
"lng_giveaway_create_subtitle" = "winners are chosen randomly";
"lng_giveaway_award_option" = "Award Specific Users";
@ -2237,23 +2253,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_giveaway_channels_title" = "Channels included in the giveaway";
"lng_giveaway_channels_this#one" = "this channel will receive {count} boost";
"lng_giveaway_channels_this#other" = "this channel will receive {count} boosts";
"lng_giveaway_channels_this_group#one" = "this group will receive {count} boost";
"lng_giveaway_channels_this_group#other" = "this group will receive {count} boosts";
"lng_giveaway_channels_add" = "Add Channel";
"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_all" = "All subscribers";
"lng_giveaway_users_all_group" = "All members";
"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_group" = "Only new members";
"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_users_about_group" = "Choose if you want to limit the giveaway only to those who joined the group after the giveaway started or to members from specific countries.";
"lng_giveaway_start" = "Start Giveaway";
"lng_giveaway_award" = "Gift Premium";
"lng_giveaway_start_sure" = "Are you sure you want to start this prepaid giveaway now? This action cannot be undone.";
"lng_giveaway_date_title" = "Date when giveaway ends";
"lng_giveaway_date" = "Date and Time";
"lng_giveaway_date_about#one" = "Choose when {count} subscriber of your channel will be randomly selected to receive Telegram Premium.";
"lng_giveaway_date_about#one" = "Choose when {count} subscriber of your channel will be randomly selected to receive Telegram Premium.";
"lng_giveaway_date_about#other" = "Choose when {count} subscribers of your channel will be randomly selected to receive Telegram Premium.";
"lng_giveaway_date_about_group#one" = "Choose when {count} members of your group will be randomly selected to receive Telegram Premium.";
"lng_giveaway_date_about_group#other" = "Choose when {count} members of your group will be randomly selected to receive Telegram Premium.";
"lng_giveaway_duration_title#one" = "Duration of Premium subscription";
"lng_giveaway_duration_title#other" = "Duration of Premium subscriptions";
"lng_giveaway_duration_price" = "{price} x {amount}";
@ -2283,8 +2306,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_giveaway_created_title" = "Giveaway created";
"lng_giveaway_created_body" = "Check your channels' {link} to see how this giveaway boosted your channel.";
"lng_giveaway_created_body_group" = "Check your groups' {link} to see how this giveaway boosted your group.";
"lng_giveaway_awarded_title" = "Premium subscriptions gifted";
"lng_giveaway_awarded_body" = "Check your channels' {link} to see how gifts boosted your channel.";
"lng_giveaway_awarded_body_group" = "Check your groups' {link} to see how gifts boosted your group.";
"lng_giveaway_created_link" = "Statistics";
"lng_prize_title" = "Congratulations!";
@ -2307,8 +2332,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_prizes_participants" = "Participants";
"lng_prizes_participants_all#one" = "All subscribers of the channel:";
"lng_prizes_participants_all#other" = "All subscribers of the channels:";
"lng_prizes_participants_all_group#one" = "All members of the group:";
"lng_prizes_participants_all_group#other" = "All members of the groups:";
"lng_prizes_participants_all_mixed#one" = "All members of the group:";
"lng_prizes_participants_all_mixed#other" = "All members of the groups and channels:";
"lng_prizes_participants_new#one" = "All users who joined the channel below after this date:";
"lng_prizes_participants_new#other" = "All users who joined the channels below after this date:";
"lng_prizes_participants_new_group#one" = "All users who joined the group below after this date:";
"lng_prizes_participants_new_group#other" = "All users who joined the groups below after this date:";
"lng_prizes_participants_new_mixed#one" = "All users who joined the group below after this date:";
"lng_prizes_participants_new_mixed#other" = "All users who joined the groups and channels below after this date:";
"lng_prizes_countries" = "from {countries}";
"lng_prizes_countries_and_one" = "{countries}, {country}";
"lng_prizes_countries_and_last" = "{countries} and {country}";
@ -2319,32 +2352,43 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_prizes_how_text" = "This giveaway is sponsored by {admins}.";
"lng_prizes_end_text" = "This giveaway was sponsored by {admins}.";
"lng_prizes_admins#one" = "the admins of {channel}, who aquired **{count} Telegram Premium** subscription {duration} for its followers";
"lng_prizes_admins#other" = "the admins of {channel}, who aquired **{count} Telegram Premium** subscriptions {duration} for its followers.";
"lng_prizes_admins#other" = "the admins of {channel}, who aquired **{count} Telegram Premium** subscriptions {duration} for its followers";
"lng_prizes_admins_group#one" = "the admins of {channel}, who aquired **{count} Telegram Premium** subscription {duration} for its members";
"lng_prizes_admins_group#other" = "the admins of {channel}, who aquired **{count} Telegram Premium** subscriptions {duration} for its members";
"lng_prizes_additional_added#one" = "{channel} also included **{count} {prize}** in the prize. Admins of the channel are responsible for delivering this prize.";
"lng_prizes_additional_added#other" = "{channel} also included **{count} {prize}** in the prizes. Admins of the channel are responsible for delivering these prizes.";
"lng_prizes_additional_added_group#one" = "{channel} also included **{count} {prize}** in the prize. Admins of the group are responsible for delivering this prize.";
"lng_prizes_additional_added_group#other" = "{channel} also included **{count} {prize}** in the prizes. Admins of the group are responsible for delivering these prizes.";
"lng_prizes_how_when_finish" = "On {date}, Telegram will automatically select {winners}.";
"lng_prizes_end_when_finish" = "On {date}, Telegram automatically selected {winners}.";
"lng_prizes_end_activated#one" = "**{count}** of the winners already used their gift link.";
"lng_prizes_end_activated#other" = "**{count}** of the winners already used their gift links.";
"lng_prizes_winners_all_of_one#one" = "{count} random subscribers of {channel}";
"lng_prizes_winners_all_of_one#one" = "{count} random subscriber of {channel}";
"lng_prizes_winners_all_of_one#other" = "{count} random subscribers of {channel}";
"lng_prizes_winners_all_of_many#one" = "{count} random subscribers of {channel} and other listed channels";
"lng_prizes_winners_all_of_many#other" = "{count} random subscribers of {channel} and other listed channels";
"lng_prizes_winners_all_of_one_group#one" = "{count} random member of {channel}";
"lng_prizes_winners_all_of_one_group#other" = "{count} random members of {channel}";
"lng_prizes_winners_all_of_many#one" = "{count} random subscriber of {channel} and other listed groups and channels";
"lng_prizes_winners_all_of_many#other" = "{count} random subscribers of {channel} and other listed groups and channels";
"lng_prizes_winners_all_of_many_group#one" = "{count} random member of {channel} and other listed groups and channels";
"lng_prizes_winners_all_of_many_group#other" = "{count} random members of {channel} and other listed groups and channels";
"lng_prizes_winners_new_of_one#one" = "{count} random user that joined {channel} after {start_date}";
"lng_prizes_winners_new_of_one#other" = "{count} random users that joined {channel} after {start_date}";
"lng_prizes_winners_new_of_many#one" = "{count} random user that joined {channel} and other listed channels after {start_date}";
"lng_prizes_winners_new_of_many#other" = "{count} random users that joined {channel} and other listed channels after {start_date}";
"lng_prizes_how_participate_one" = "To take part in this giveaway please join channel {channel} before {date}.";
"lng_prizes_how_participate_many" = "To take part in this giveaway please join channel {channel} and other listed channels before {date}.";
"lng_prizes_winners_new_of_many#one" = "{count} random user that joined {channel} and other listed groups and channels after {start_date}";
"lng_prizes_winners_new_of_many#other" = "{count} random users that joined {channel} and other listed groups and channels after {start_date}";
"lng_prizes_how_participate_one" = "To take part in this giveaway please join {channel} before {date}.";
"lng_prizes_how_participate_many" = "To take part in this giveaway please join {channel} and other listed groups and channels before {date}.";
"lng_prizes_how_no_admin" = "You are not eligible to participate in this giveaway, because you are an admin of participating channel ({channel}).";
"lng_prizes_how_no_admin_group" = "You are not eligible to participate in this giveaway, because you are an admin of participating group ({channel}).";
"lng_prizes_how_no_joined" = "You are not eligible to participate in this giveaway, because you joined this channel on {date}, which is before the contest started.";
"lng_prizes_how_no_joined_group" = "You are not eligible to participate in this giveaway, because you joined this group on {date}, which is before the contest started.";
"lng_prizes_how_no_country" = "You are not eligible to participate in this giveaway, because your country is not included in the terms of the giveaway.";
"lng_prizes_how_yes_joined_one" = "You are participating in this giveaway, because you have joined channel {channel}.";
"lng_prizes_how_yes_joined_many" = "You are participating in this giveaway, because you have joined channel {channel} (and other listed channels).";
"lng_prizes_how_yes_joined_one" = "You are participating in this giveaway, because you have joined {channel}.";
"lng_prizes_how_yes_joined_many" = "You are participating in this giveaway, because you have joined {channel} (and other listed groups and channels).";
"lng_prizes_you_won" = "You won a prize in this giveaway {cup}";
"lng_prizes_view_prize" = "View my prize";
"lng_prizes_you_didnt" = "You didn't win a prize in this giveaway.";
"lng_prizes_cancelled" = "The channel cancelled the prizes by reversing the payment for them.";
"lng_prizes_cancelled_group" = "The channel cancelled the prizes by reversing the payment for them.";
"lng_prizes_badge" = "x{amount}";
"lng_prizes_results_title" = "Winners Selected!";
@ -4592,10 +4636,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_boosts_level" = "Level";
"lng_boosts_existing" = "Existing boosts";
"lng_boosts_premium_audience" = "Premium subscribers";
"lng_boosts_premium_members" = "Premium members";
"lng_boosts_next_level" = "Boosts to level up";
"lng_boosts_list_title#one" = "{count} Boost";
"lng_boosts_list_title#other" = "{count} Boosts";
"lng_boosts_list_subtext" = "Your channel is currently boosted by these users.";
"lng_boosts_list_subtext_group" = "Your group is currently boosted by these users.";
"lng_boosts_show_more_boosts#one" = "Show {count} More Boosts";
"lng_boosts_show_more_boosts#other" = "Show {count} More Boosts";
"lng_boosts_show_more_gifts#one" = "Show {count} More Boosts";
@ -4603,8 +4649,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_boosts_list_status" = "boost expires on {date}";
"lng_boosts_link_title" = "Link for boosting";
"lng_boosts_link_subtext" = "Share this link with your subscribers to get more boosts.";
"lng_boosts_link_subtext_group" = "Share this link with the members of your group to get more boosts.";
"lng_boosts_get_boosts" = "Get Boosts via Gifts";
"lng_boosts_get_boosts_subtext" = "Get more boosts for your channel by gifting Telegram Premium to your subscribers.";
"lng_boosts_get_boosts_subtext_group" = "Get more boosts for your group by gifting Telegram Premium to the members.";
"lng_boosts_list_unclaimed" = "Unclaimed";
"lng_boosts_list_pending" = "To be distributed";
"lng_boosts_list_pending_about" = "The recipient will be selected when the giveaway ends.";

View File

@ -604,7 +604,7 @@ rpl::producer<rpl::no_value, QString> Boosts::request() {
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
const auto channel = _peer->asChannel();
if (!channel || channel->isMegagroup()) {
if (!channel) {
return lifetime;
}
@ -628,6 +628,7 @@ rpl::producer<rpl::no_value, QString> Boosts::request() {
const auto slots = data.vmy_boost_slots();
_boostStatus.overview = Data::BoostsOverview{
.group = channel->isMegagroup(),
.mine = slots ? int(slots->v.size()) : 0,
.level = std::max(data.vlevel().v, 0),
.boostCount = std::max(

View File

@ -1363,20 +1363,24 @@ void GiveawayInfoBox(
? start->quantity
: (results->winnersCount + results->unclaimedCount);
const auto months = start ? start->months : results->months;
const auto group = !start->channels.empty()
&& start->channels.front()->isMegagroup();
text.append((finished
? tr::lng_prizes_end_text
: tr::lng_prizes_how_text)(
tr::now,
lt_admins,
tr::lng_prizes_admins(
tr::now,
lt_count,
quantity,
lt_channel,
Ui::Text::Bold(first),
lt_duration,
TextWithEntities{ GiftDuration(months) },
Ui::Text::RichLangValue),
(group
? tr::lng_prizes_admins_group
: tr::lng_prizes_admins)(
tr::now,
lt_count,
quantity,
lt_channel,
Ui::Text::Bold(first),
lt_duration,
TextWithEntities{ GiftDuration(months) },
Ui::Text::RichLangValue),
Ui::Text::RichLangValue));
const auto many = start
? (start->channels.size() > 1)
@ -1387,8 +1391,12 @@ void GiveawayInfoBox(
const auto all = start ? start->all : results->all;
auto winners = all
? (many
? tr::lng_prizes_winners_all_of_many
: tr::lng_prizes_winners_all_of_one)(
? (group
? tr::lng_prizes_winners_all_of_many_group
: tr::lng_prizes_winners_all_of_many)
: (group
? tr::lng_prizes_winners_all_of_one_group
: tr::lng_prizes_winners_all_of_one))(
tr::now,
lt_count,
count,
@ -1411,15 +1419,17 @@ void GiveawayInfoBox(
? results->additionalPrize
: start->additionalPrize;
if (!additionalPrize.isEmpty()) {
text.append("\n\n").append(tr::lng_prizes_additional_added(
tr::now,
lt_count,
count,
lt_channel,
Ui::Text::Bold(first),
lt_prize,
TextWithEntities{ additionalPrize },
Ui::Text::RichLangValue));
text.append("\n\n").append((group
? tr::lng_prizes_additional_added_group
: tr::lng_prizes_additional_added)(
tr::now,
lt_count,
count,
lt_channel,
Ui::Text::Bold(first),
lt_prize,
TextWithEntities{ additionalPrize },
Ui::Text::RichLangValue));
}
const auto untilDate = start
? start->untilDate
@ -1448,18 +1458,25 @@ void GiveawayInfoBox(
if (info.adminChannelId) {
const auto channel = controller->session().data().channel(
info.adminChannelId);
text.append("\n\n").append(tr::lng_prizes_how_no_admin(
tr::now,
lt_channel,
Ui::Text::Bold(channel->name()),
Ui::Text::RichLangValue));
text.append("\n\n").append((channel->isMegagroup()
? tr::lng_prizes_how_no_admin_group
: tr::lng_prizes_how_no_admin)(
tr::now,
lt_channel,
Ui::Text::Bold(channel->name()),
Ui::Text::RichLangValue));
} else if (info.tooEarlyDate) {
text.append("\n\n").append(tr::lng_prizes_how_no_joined(
tr::now,
lt_date,
Ui::Text::Bold(
langDateTime(base::unixtime::parse(info.tooEarlyDate))),
Ui::Text::RichLangValue));
const auto channel = controller->session().data().channel(
info.adminChannelId);
text.append("\n\n").append((channel->isMegagroup()
? tr::lng_prizes_how_no_joined_group
: tr::lng_prizes_how_no_joined)(
tr::now,
lt_date,
Ui::Text::Bold(
langDateTime(
base::unixtime::parse(info.tooEarlyDate))),
Ui::Text::RichLangValue));
} else if (!info.disallowedCountry.isEmpty()) {
text.append("\n\n").append(tr::lng_prizes_how_no_country(
tr::now,
@ -1499,7 +1516,9 @@ void GiveawayInfoBox(
box.get(),
object_ptr<Ui::FlatLabel>(
box.get(),
tr::lng_prizes_cancelled(),
(group
? tr::lng_prizes_cancelled_group()
: tr::lng_prizes_cancelled()),
st::giveawayRefundedLabel),
st::giveawayRefundedPadding),
{ padding.left(), 0, padding.right(), padding.bottom() });

View File

@ -313,21 +313,23 @@ void Controller::rowClicked(not_null<PeerListRow*> row) {
}
}
object_ptr<Ui::BoxContent> ReassignBoostFloodBox(int seconds) {
object_ptr<Ui::BoxContent> ReassignBoostFloodBox(int seconds, bool group) {
const auto days = seconds / 86400;
const auto hours = seconds / 3600;
const auto minutes = seconds / 60;
return Ui::MakeInformBox({
.text = tr::lng_boost_error_flood_text(
lt_left,
rpl::single(Ui::Text::Bold((days > 1)
? tr::lng_days(tr::now, lt_count, days)
: (hours > 1)
? tr::lng_hours(tr::now, lt_count, hours)
: (minutes > 1)
? tr::lng_minutes(tr::now, lt_count, minutes)
: tr::lng_seconds(tr::now, lt_count, seconds))),
Ui::Text::RichLangValue),
.text = (group
? tr::lng_boost_error_flood_text_group
: tr::lng_boost_error_flood_text)(
lt_left,
rpl::single(Ui::Text::Bold((days > 1)
? tr::lng_days(tr::now, lt_count, days)
: (hours > 1)
? tr::lng_hours(tr::now, lt_count, hours)
: (minutes > 1)
? tr::lng_minutes(tr::now, lt_count, minutes)
: tr::lng_seconds(tr::now, lt_count, seconds))),
Ui::Text::RichLangValue),
.title = tr::lng_boost_error_flood_title(),
});
}
@ -445,7 +447,9 @@ object_ptr<Ui::BoxContent> ReassignBoostsBox(
const auto now = base::unixtime::now();
if (from.size() == 1 && from.front().cooldown > now) {
cancel();
return ReassignBoostFloodBox(from.front().cooldown - now);
return ReassignBoostFloodBox(
from.front().cooldown - now,
to->owner().peer(from.front().peerId)->isMegagroup());
} else if (from.size() == 1 && from.front().peerId) {
return ReassignBoostSingleBox(to, from.front(), reassign, cancel);
}

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Data {
struct BoostsOverview final {
bool group = false;
int mine = 0;
int level = 0;
int boostCount = 0;

View File

@ -4796,11 +4796,13 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
auto prepareGiveawayLaunch = [&](const MTPDmessageActionGiveawayLaunch &action) {
auto result = PreparedServiceText();
result.links.push_back(fromLink());
result.text = tr::lng_action_giveaway_started(
tr::now,
lt_from,
fromLinkText(), // Link 1.
Ui::Text::WithEntities);
result.text = (_history->peer->isMegagroup()
? tr::lng_action_giveaway_started_group
: tr::lng_action_giveaway_started)(
tr::now,
lt_from,
fromLinkText(), // Link 1.
Ui::Text::WithEntities);
return result;
};

View File

@ -698,12 +698,27 @@ auto GenerateGiveawayStart(
Ui::Text::Bold(tr::lng_prizes_participants(tr::now)),
st::chatGiveawayPrizesTitleMargin);
const auto hasChannel = ranges::any_of(
data->channels,
&ChannelData::isBroadcast);
const auto hasGroup = ranges::any_of(
data->channels,
&ChannelData::isMegagroup);
const auto mixed = (hasChannel && hasGroup);
pushText({ (data->all
? tr::lng_prizes_participants_all
: tr::lng_prizes_participants_new)(
tr::now,
lt_count,
data->channels.size()),
? (mixed
? tr::lng_prizes_participants_all_mixed
: hasGroup
? tr::lng_prizes_participants_all_group
: tr::lng_prizes_participants_all)
: (mixed
? tr::lng_prizes_participants_new_mixed
: hasGroup
? tr::lng_prizes_participants_new_group
: tr::lng_prizes_participants_new))(
tr::now,
lt_count,
data->channels.size()),
}, st::chatGiveawayParticipantsMargin);
auto list = ranges::views::all(

View File

@ -89,7 +89,8 @@ constexpr auto kAdditionalPrizeLengthMax = 128;
void AddPremiumTopBarWithDefaultTitleBar(
not_null<Ui::GenericBox*> box,
rpl::producer<> showFinished,
rpl::producer<QString> titleText) {
rpl::producer<QString> titleText,
bool group) {
struct State final {
Ui::Animations::Simple animation;
Ui::Text::String title;
@ -175,7 +176,9 @@ void AddPremiumTopBarWithDefaultTitleBar(
st::startGiveawayCover,
nullptr,
tr::lng_giveaway_new_title(),
tr::lng_giveaway_new_about(Ui::Text::RichLangValue),
(group
? tr::lng_giveaway_new_about_group
: tr::lng_giveaway_new_about)(Ui::Text::RichLangValue),
true,
false);
bar->setAttribute(Qt::WA_TransparentForMouseEvents);
@ -265,6 +268,7 @@ void CreateGiveawayBox(
rpl::variable<bool> confirmButtonBusy = true;
};
const auto group = peer->isMegagroup();
const auto state = box->lifetime().make_state<State>(peer);
const auto typeGroup = std::make_shared<GiveawayGroup>();
@ -276,7 +280,8 @@ void CreateGiveawayBox(
state->typeValue.value(
) | rpl::map(rpl::mappers::_1 == GiveawayType::Random),
tr::lng_giveaway_start(),
tr::lng_giveaway_award()));
tr::lng_giveaway_award()),
peer->isMegagroup());
{
const auto &padding = st::giveawayGiftCodeCoverDividerPadding;
Ui::AddSkip(box->verticalLayout(), padding.bottom());
@ -329,7 +334,8 @@ void CreateGiveawayBox(
object_ptr<Giveaway::GiveawayTypeRow>(
box,
GiveawayType::Random,
tr::lng_giveaway_create_subtitle()));
tr::lng_giveaway_create_subtitle(),
group));
row->addRadio(typeGroup);
row->setClickedCallback([=] {
state->typeValue.force_assign(GiveawayType::Random);
@ -351,7 +357,8 @@ void CreateGiveawayBox(
: tr::lng_giveaway_award_chosen(
lt_count,
rpl::single(selected.size()) | tr::to_count());
}) | rpl::flatten_latest()));
}) | rpl::flatten_latest(),
group));
row->addRadio(typeGroup);
row->setClickedCallback([=] {
auto initBox = [=](not_null<PeerListBox*> peersBox) {
@ -534,12 +541,14 @@ void CreateGiveawayBox(
auto &list = state->selectedToSubscribe;
list.erase(ranges::remove(list, peer), end(list));
}, box->lifetime());
listState->controller.setTopStatus(tr::lng_giveaway_channels_this(
lt_count,
state->sliderValue.value(
) | rpl::map([=](int v) -> float64 {
return state->apiOptions.giveawayBoostsPerPremium() * v;
})));
listState->controller.setTopStatus((peer->isMegagroup()
? tr::lng_giveaway_channels_this_group
: tr::lng_giveaway_channels_this)(
lt_count,
state->sliderValue.value(
) | rpl::map([=](int v) -> float64 {
return state->apiOptions.giveawayBoostsPerPremium() * v;
})));
using IconType = Settings::IconType;
Settings::AddButtonWithIcon(
@ -638,7 +647,8 @@ void CreateGiveawayBox(
object_ptr<Giveaway::GiveawayTypeRow>(
box,
GiveawayType::AllMembers,
rpl::duplicate(subtitle)));
rpl::duplicate(subtitle),
group));
row->addRadio(membersGroup);
row->setClickedCallback(createCallback(GiveawayType::AllMembers));
}
@ -646,14 +656,17 @@ void CreateGiveawayBox(
object_ptr<Giveaway::GiveawayTypeRow>(
box,
GiveawayType::OnlyNewMembers,
std::move(subtitle)));
std::move(subtitle),
group));
row->addRadio(membersGroup);
row->setClickedCallback(createCallback(GiveawayType::OnlyNewMembers));
Ui::AddSkip(countriesContainer);
Ui::AddDividerText(
countriesContainer,
tr::lng_giveaway_users_about());
(group
? tr::lng_giveaway_users_about_group()
: tr::lng_giveaway_users_about()));
Ui::AddSkip(countriesContainer);
}
@ -892,9 +905,11 @@ void CreateGiveawayBox(
auto terms = object_ptr<Ui::VerticalLayout>(dateContainer);
terms->add(object_ptr<Ui::FlatLabel>(
terms,
tr::lng_giveaway_date_about(
lt_count,
state->sliderValue.value() | tr::to_count()),
(group
? tr::lng_giveaway_date_about_group
: tr::lng_giveaway_date_about)(
lt_count,
state->sliderValue.value() | tr::to_count()),
st::boxDividerLabel));
Ui::AddSkip(terms.data());
Ui::AddSkip(terms.data());
@ -907,9 +922,11 @@ void CreateGiveawayBox(
} else {
Ui::AddDividerText(
dateContainer,
tr::lng_giveaway_date_about(
lt_count,
state->sliderValue.value() | tr::to_count()));
(group
? tr::lng_giveaway_date_about_group
: tr::lng_giveaway_date_about)(
lt_count,
state->sliderValue.value() | tr::to_count()));
Ui::AddSkip(dateContainer);
}
}
@ -1036,12 +1053,17 @@ void CreateGiveawayBox(
}
return false;
};
const auto group = peer->isMegagroup();
const auto title = isSpecific
? tr::lng_giveaway_awarded_title
: tr::lng_giveaway_created_title;
const auto body = isSpecific
? tr::lng_giveaway_awarded_body
: tr::lng_giveaway_created_body;
? (group
? tr::lng_giveaway_awarded_body_group
: tr::lng_giveaway_awarded_body)
: (group
? tr::lng_giveaway_created_body_group
: tr::lng_giveaway_created_body);
show->showToast({
.text = Ui::Text::Bold(
title(tr::now)).append('\n').append(

View File

@ -293,14 +293,13 @@ void MyChannelsListController::setCheckError(Fn<bool(int)> callback) {
std::unique_ptr<PeerListRow> MyChannelsListController::createRow(
not_null<ChannelData*> channel) const {
if (channel->isMegagroup()) {
return nullptr;
}
auto row = std::make_unique<PeerListRow>(channel);
row->setCustomStatus(tr::lng_chat_status_subscribers(
tr::now,
lt_count,
channel->membersCount()));
row->setCustomStatus((channel->isBroadcast()
? tr::lng_chat_status_subscribers
: tr::lng_chat_status_members)(
tr::now,
lt_count,
channel->membersCount()));
return row;
}
@ -358,19 +357,18 @@ void SelectedChannelsListController::prepare() {
std::unique_ptr<PeerListRow> SelectedChannelsListController::createRow(
not_null<ChannelData*> channel) const {
if (channel->isMegagroup()) {
return nullptr;
}
const auto isYourChannel = (_peer->asChannel() == channel);
auto row = isYourChannel
? std::make_unique<PeerListRow>(channel)
: std::make_unique<ChannelRow>(channel);
row->setCustomStatus(isYourChannel
? QString()
: tr::lng_chat_status_subscribers(
tr::now,
lt_count,
channel->membersCount()));
: (channel->isMegagroup()
? tr::lng_chat_status_members
: tr::lng_chat_status_subscribers)(
tr::now,
lt_count,
channel->membersCount()));
return row;
}

View File

@ -24,7 +24,8 @@ constexpr auto kColorIndexRandom = int(2);
GiveawayTypeRow::GiveawayTypeRow(
not_null<Ui::RpWidget*> parent,
Type type,
rpl::producer<QString> subtitle)
rpl::producer<QString> subtitle,
bool group)
: GiveawayTypeRow(
parent,
type,
@ -34,8 +35,12 @@ GiveawayTypeRow::GiveawayTypeRow(
: (type == Type::Random)
? tr::lng_giveaway_create_option()
: (type == Type::AllMembers)
? tr::lng_giveaway_users_all()
: tr::lng_giveaway_users_new(),
? (group
? tr::lng_giveaway_users_all_group()
: tr::lng_giveaway_users_all())
: (group
? tr::lng_giveaway_users_new_group()
: tr::lng_giveaway_users_new()),
std::move(subtitle),
QImage()) {
}

View File

@ -32,7 +32,8 @@ public:
GiveawayTypeRow(
not_null<Ui::RpWidget*> parent,
Type type,
rpl::producer<QString> subtitle);
rpl::producer<QString> subtitle,
bool group);
GiveawayTypeRow(
not_null<Ui::RpWidget*> parent,

View File

@ -128,7 +128,9 @@ void FillOverview(
addSub(
topRightLabel,
stats.premiumMemberPercentage,
tr::lng_boosts_premium_audience);
(stats.group
? tr::lng_boosts_premium_members
: tr::lng_boosts_premium_audience));
addSub(
bottomLeftLabel,
0,
@ -248,7 +250,9 @@ void FillGetBoostsButton(
(st.height + rect::m::sum::v(st.padding) - icon.height()) / 2,
})->show();
Ui::AddSkip(content);
Ui::AddDividerText(content, tr::lng_boosts_get_boosts_subtext());
Ui::AddDividerText(content, peer->isMegagroup()
? tr::lng_boosts_get_boosts_subtext_group()
: tr::lng_boosts_get_boosts_subtext());
}
} // namespace
@ -479,7 +483,9 @@ void InnerWidget::fill() {
Ui::AddSkip(inner);
Ui::AddSkip(inner);
Ui::AddDividerText(inner, tr::lng_boosts_list_subtext());
Ui::AddDividerText(inner, status.overview.group
? tr::lng_boosts_list_subtext_group()
: tr::lng_boosts_list_subtext());
}
Ui::AddSkip(inner);
@ -488,7 +494,9 @@ void InnerWidget::fill() {
Ui::AddSkip(inner, st::boostsLinkSkip);
FillShareLink(inner, _show, status.link, _peer);
Ui::AddSkip(inner);
Ui::AddDividerText(inner, tr::lng_boosts_link_subtext());
Ui::AddDividerText(inner, status.overview.group
? tr::lng_boosts_link_subtext_group()
: tr::lng_boosts_link_subtext());
FillGetBoostsButton(inner, _controller, _show, _peer, reloadOnDone);

View File

@ -165,9 +165,13 @@ void BoostBox(
rpl::single(name))
: !counters.nextLevelBoosts
? tr::lng_boost_channel_title_max()
: !counters.level
? tr::lng_boost_channel_title_first()
: tr::lng_boost_channel_title_more();
: counters.level
? (data.group
? tr::lng_boost_channel_title_more_group()
: tr::lng_boost_channel_title_more())
: (data.group
? tr::lng_boost_channel_title_first_group()
: tr::lng_boost_channel_title_first());
}) | rpl::flatten_latest();
auto repeated = state->data.value(
) | rpl::map([=](BoostCounters counters) {
@ -189,25 +193,33 @@ void BoostBox(
return (counters.mine || full)
? (left
? (!counters.level
? tr::lng_boost_channel_you_first(
lt_count,
rpl::single(float64(left)),
Ui::Text::RichLangValue)
: tr::lng_boost_channel_you_more(
lt_count,
rpl::single(float64(left)),
lt_post,
std::move(post),
Ui::Text::RichLangValue))
? (data.group
? tr::lng_boost_channel_you_first_group
: tr::lng_boost_channel_you_first)(
lt_count,
rpl::single(float64(left)),
Ui::Text::RichLangValue)
: (data.group
? tr::lng_boost_channel_you_more_group
: tr::lng_boost_channel_you_more)(
lt_count,
rpl::single(float64(left)),
lt_post,
std::move(post),
Ui::Text::RichLangValue))
: (!counters.level
? tr::lng_boost_channel_reached_first(
Ui::Text::RichLangValue)
: tr::lng_boost_channel_reached_more(
lt_count,
rpl::single(float64(counters.level)),
lt_post,
std::move(post),
Ui::Text::RichLangValue)))
? (data.group
? tr::lng_boost_channel_reached_first_group
: tr::lng_boost_channel_reached_first)(
Ui::Text::RichLangValue)
: (data.group
? tr::lng_boost_channel_reached_more_group
: tr::lng_boost_channel_reached_more)(
lt_count,
rpl::single(float64(counters.level)),
lt_post,
std::move(post),
Ui::Text::RichLangValue)))
: !counters.level
? tr::lng_boost_channel_needs_first(
lt_count,
@ -244,6 +256,8 @@ void BoostBox(
? tr::lng_box_ok()
: (counters.mine > 0)
? tr::lng_boost_again_button()
: data.group
? tr::lng_boost_group_button()
: tr::lng_boost_channel_button();
}) | rpl::flatten_latest();
@ -408,9 +422,11 @@ object_ptr<Ui::RpWidget> MakeLinkLabel(
return result;
}
void BoostBoxAlready(not_null<GenericBox*> box) {
void BoostBoxAlready(not_null<GenericBox*> box, bool group) {
ConfirmBox(box, {
.text = tr::lng_boost_error_already_text(Text::RichLangValue),
.text = (group
? tr::lng_boost_error_already_text_group
: tr::lng_boost_error_already_text)(Text::RichLangValue),
.title = tr::lng_boost_error_already_title(),
.inform = true,
});
@ -435,16 +451,23 @@ void GiftForBoostsBox(
});
}
void GiftedNoBoostsBox(not_null<GenericBox*> box) {
void GiftedNoBoostsBox(not_null<GenericBox*> box, bool group) {
InformBox(box, {
.text = tr::lng_boost_error_gifted_text(Text::RichLangValue),
.text = (group
? tr::lng_boost_error_gifted_text_group
: tr::lng_boost_error_gifted_text)(Text::RichLangValue),
.title = tr::lng_boost_error_gifted_title(),
});
}
void PremiumForBoostsBox(not_null<GenericBox*> box, Fn<void()> buyPremium) {
void PremiumForBoostsBox(
not_null<GenericBox*> box,
bool group,
Fn<void()> buyPremium) {
ConfirmBox(box, {
.text = tr::lng_boost_error_premium_text(Text::RichLangValue),
.text = (group
? tr::lng_boost_error_premium_text_group
: tr::lng_boost_error_premium_text)(Text::RichLangValue),
.confirmed = buyPremium,
.confirmText = tr::lng_boost_error_premium_yes(),
.title = tr::lng_boost_error_premium_title(),

View File

@ -34,6 +34,7 @@ struct BoostBoxData {
QString name;
BoostCounters boost;
bool allowMulti = false;
bool group = false;
};
void BoostBox(
@ -41,14 +42,17 @@ void BoostBox(
BoostBoxData data,
Fn<void(Fn<void(BoostCounters)>)> boost);
void BoostBoxAlready(not_null<GenericBox*> box);
void BoostBoxAlready(not_null<GenericBox*> box, bool group);
void GiftForBoostsBox(
not_null<GenericBox*> box,
QString channel,
int receive,
bool again);
void GiftedNoBoostsBox(not_null<GenericBox*> box);
void PremiumForBoostsBox(not_null<GenericBox*> box, Fn<void()> buyPremium);
void GiftedNoBoostsBox(not_null<GenericBox*> box, bool group);
void PremiumForBoostsBox(
not_null<GenericBox*> box,
bool group,
Fn<void()> buyPremium);
struct AskBoostChannelColor {
int requiredLevel = 0;

View File

@ -1046,10 +1046,9 @@ void Filler::addViewStatistics() {
}
}, &st::menuIconStats);
}
if (!channel->isMegagroup()
&& (canGetStats
|| channel->amCreator()
|| channel->canPostStories())) {
if (canGetStats
|| channel->amCreator()
|| channel->canPostStories()) {
_addAction(tr::lng_boosts_title(tr::now), [=] {
if (const auto strong = weak.get()) {
controller->showSection(Info::Boosts::Make(peer));

View File

@ -552,7 +552,7 @@ void SessionNavigation::showPeerByLinkResolved(
} else {
showPeerInfo(peer, params);
}
} else if (resolveType == ResolveType::Boost && peer->isBroadcast()) {
} else if (resolveType == ResolveType::Boost && peer->isChannel()) {
resolveBoostState(peer->asChannel());
} else {
// Show specific posts only in channels / supergroups.
@ -631,6 +631,7 @@ void SessionNavigation::resolveBoostState(not_null<ChannelData*> channel) {
.name = channel->name(),
.boost = ParseBoostCounters(result),
.allowMulti = (BoostsForGift(_session) > 0),
.group = channel->isMegagroup(),
}, submit));
}).fail([=](const MTP::Error &error) {
_boostStateResolving = nullptr;
@ -659,10 +660,12 @@ void SessionNavigation::applyBoost(
uiShow()->show(
Box(Ui::GiftForBoostsBox, name, receive, again));
} else {
uiShow()->show(Box(Ui::BoostBoxAlready));
uiShow()->show(
Box(Ui::BoostBoxAlready, channel->isMegagroup()));
}
} else if (!_session->premium()) {
uiShow()->show(Box(Ui::PremiumForBoostsBox, [=] {
const auto group = channel->isMegagroup();
uiShow()->show(Box(Ui::PremiumForBoostsBox, group, [=] {
const auto id = peerToChannel(channel->id).bare;
Settings::ShowPremium(
parentController(),
@ -674,7 +677,8 @@ void SessionNavigation::applyBoost(
uiShow()->show(
Box(Ui::GiftForBoostsBox, name, receive, again));
} else {
uiShow()->show(Box(Ui::GiftedNoBoostsBox));
uiShow()->show(
Box(Ui::GiftedNoBoostsBox, channel->isMegagroup()));
}
done({});
} else {