diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index d0c8c8a9b..be00ea9c9 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2475,6 +2475,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_boost_channel_needs_level_reactions#one" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as a reaction."; "lng_boost_channel_needs_level_reactions#other" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as reactions."; +"lng_boost_channel_title_cpm" = "Boost Channel"; +"lng_boost_channel_needs_level_cpm#one" = "Your channel needs to reach **Level {count}** to switch off ads."; +"lng_boost_channel_needs_level_cpm#other" = "Your channel needs to reach **Level {count}** to switch off ads."; + "lng_boost_group_title_emoji" = "Enable emoji pack"; "lng_boost_group_needs_level_emoji#one" = "Your group needs to reach **Level {count}** to set emoji pack."; "lng_boost_group_needs_level_emoji#other" = "Your group needs to reach **Level {count}** to set emoji pack."; diff --git a/Telegram/SourceFiles/api/api_statistics.cpp b/Telegram/SourceFiles/api/api_statistics.cpp index fa617293f..2779c7900 100644 --- a/Telegram/SourceFiles/api/api_statistics.cpp +++ b/Telegram/SourceFiles/api/api_statistics.cpp @@ -779,7 +779,7 @@ rpl::producer EarnStatistics::request() { ).done([=](const MTPmessages_ChatFull &result) { result.data().vfull_chat().match([&]( const MTPDchannelFull &d) { - _data.minCpm = d.vsponsored_min_cpm().value_or(-1); + _data.switchedOff = d.is_restricted_sponsored(); }, [](const auto &) { }); consumer.put_done(); diff --git a/Telegram/SourceFiles/data/data_channel_earn.h b/Telegram/SourceFiles/data/data_channel_earn.h index 7b47eff80..c4db98f28 100644 --- a/Telegram/SourceFiles/data/data_channel_earn.h +++ b/Telegram/SourceFiles/data/data_channel_earn.h @@ -62,7 +62,7 @@ struct EarnStatistics final { EarnInt availableBalance = 0; EarnInt overallRevenue = 0; float64 usdRate = 0.; - int minCpm = -1; + bool switchedOff = false; EarnHistorySlice firstHistorySlice; }; diff --git a/Telegram/SourceFiles/data/data_sponsored_messages.cpp b/Telegram/SourceFiles/data/data_sponsored_messages.cpp index ae37e9191..a88111fbe 100644 --- a/Telegram/SourceFiles/data/data_sponsored_messages.cpp +++ b/Telegram/SourceFiles/data/data_sponsored_messages.cpp @@ -566,3 +566,21 @@ SponsoredMessages::State SponsoredMessages::state( } } // namespace Data + +namespace Api { + +void RestrictSponsored( + not_null channel, + bool restricted, + Fn failed) { + channel->session().api().request(MTPchannels_RestrictSponsoredMessages( + channel->inputChannel, + MTP_bool(restricted)) + ).done([=](const MTPUpdates &updates) { + channel->session().api().applyUpdates(updates); + }).fail([=](const MTP::Error &error) { + failed(error.type()); + }).send(); +} + +} // namespace Api diff --git a/Telegram/SourceFiles/data/data_sponsored_messages.h b/Telegram/SourceFiles/data/data_sponsored_messages.h index 04f0cd196..e124dd1d4 100644 --- a/Telegram/SourceFiles/data/data_sponsored_messages.h +++ b/Telegram/SourceFiles/data/data_sponsored_messages.h @@ -158,3 +158,13 @@ private: }; } // namespace Data + +namespace Api { + +void RestrictSponsored( + not_null channel, + bool restricted, + Fn failed); + +} // namespace Api + diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp index 0526f52bb..22c8db5c6 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp @@ -13,9 +13,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/peers/edit_peer_color_box.h" // AddLevelBadge. #include "chat_helpers/stickers_emoji_pack.h" #include "core/ui_integration.h" // Core::MarkedTextContext. +#include "data/data_channel.h" #include "data/data_peer.h" #include "data/data_premium_limits.h" #include "data/data_session.h" +#include "data/data_sponsored_messages.h" #include "data/stickers/data_custom_emoji.h" #include "info/channel_statistics/earn/info_earn_widget.h" #include "info/info_controller.h" @@ -24,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "main/main_session.h" #include "statistics/chart_widget.h" +#include "ui/boxes/boost_box.h" #include "ui/controls/userpic_button.h" #include "ui/effects/animation_value_f.h" #include "ui/effects/fade_animation.h" @@ -822,121 +825,56 @@ void InnerWidget::fill() { Ui::AddSkip(container); if (const auto channel = _peer->asChannel()) { constexpr auto kMaxCPM = 50; // Debug. + const auto requiredLevel = Data::LevelLimits(session) + .channelRestrictSponsoredLevelMin(); const auto &phrase = tr::lng_channel_earn_off; const auto button = container->add(object_ptr( container, phrase(), - st::settingsButtonNoIcon)); + st::settingsButtonNoIconLocked)); + const auto toggled = lifetime().make_state>(); + const auto isLocked = channel->levelHint() < requiredLevel; + const auto reason = Ui::AskBoostReason{ + .data = Ui::AskBoostCpm{ .requiredLevel = requiredLevel }, + }; AddLevelBadge( - Data::LevelLimits(session).channelRestrictSponsoredLevelMin(), + requiredLevel, button, nullptr, channel, QMargins(st::boxRowPadding.left(), 0, 0, 0), phrase()); - const auto wrap = container->add( - object_ptr>( - container, - object_ptr(container)), - st::boxRowPadding); - const auto inner = wrap->entity(); - Ui::AddSkip(inner); - Ui::AddSkip(inner); - const auto line = inner->add(object_ptr(inner)); - Ui::AddSkip(inner); - const auto left = Ui::CreateChild( - line, - tr::lng_channel_earn_cpm_min(), - st::defaultFlatLabel); - const auto center = Ui::CreateChild( - line, - st::defaultFlatLabel); - const auto fade = lifetime().make_state(center); - fade->setUpdatedCallback([=](float64 o) { center->setOpacity(o); }); - const auto right = Ui::CreateChild( - line, - st::defaultFlatLabel); - addEmojiToMajor(right, kMaxCPM * Data::kEarnMultiplier); - const auto slider = Ui::CreateChild( - line, - st::settingsScale); - rpl::combine( - line->sizeValue(), - left->sizeValue(), - center->sizeValue(), - right->sizeValue() - ) | rpl::start_with_next([=]( - const QSize &s, - const QSize &leftSize, - const QSize ¢erSize, - const QSize &rightSize) { - const auto sliderHeight = st::settingsScale.seekSize.height(); - line->resize( - line->width(), - leftSize.height() + sliderHeight * 2); - { - const auto r = line->rect(); - slider->setGeometry( - 0, - r.height() - sliderHeight, - r.width(), - sliderHeight); + button->toggleOn(rpl::single( + data.switchedOff + ) | rpl::then(toggled->events())); + button->setToggleLocked(isLocked); + + button->toggledChanges( + ) | rpl::start_with_next([=](bool value) { + if (isLocked && value) { + toggled->fire(false); + CheckBoostLevel( + _controller->uiShow(), + _peer, + [=](int level) { + return (level < requiredLevel) + ? std::make_optional(reason) + : std::nullopt; + }, + [] {}); } - left->moveToLeft(0, 0); - right->moveToRight(0, 0); - center->moveToLeft((s.width() - centerSize.width()) / 2, 0); - }, line->lifetime()); - - const auto updateLabels = [=](int cpm) { - const auto activeColor = st::windowActiveTextFg->c; - left->setTextColorOverride(!cpm - ? std::make_optional(activeColor) - : std::nullopt); - - if (cpm > 0 && cpm < kMaxCPM) { - center->setMarkedText( - tr::lng_channel_earn_cpm( - tr::now, - lt_count, - cpm, - lt_emoji, - EmojiCurrency(session), - Ui::Text::RichLangValue), - makeContext(center)); - fade->fadeIn(st::channelEarnFadeDuration); - } else { - fade->fadeOut(st::channelEarnFadeDuration); + if (!isLocked) { + Api::RestrictSponsored(channel, value, [=](const QString &e) { + toggled->fire(false); + _controller->uiShow()->showToast(e); + }); } - center->setTextColorOverride(activeColor); - - right->setTextColorOverride((cpm == kMaxCPM) - ? std::make_optional(activeColor) - : std::nullopt); - }; - const auto current = std::max(0, data.minCpm); - slider->setPseudoDiscrete( - kMaxCPM + 1, - [=](int index) { return index; }, - current, - updateLabels, - updateLabels); - updateLabels(current); - - wrap->toggle(false, anim::type::instant); - button->toggleOn( - rpl::single(false) // Debug. - )->toggledChanges( - ) | rpl::filter([=](bool toggled) { - return true; - }) | rpl::start_with_next([=](bool toggled) { - wrap->toggle(toggled, anim::type::normal); - }, container->lifetime()); + }, button->lifetime()); Ui::AddSkip(container); Ui::AddDividerText(container, tr::lng_channel_earn_off_about()); - Ui::ToggleChildrenVisibility(line, true); } Ui::AddSkip(container); diff --git a/Telegram/SourceFiles/ui/boxes/boost_box.cpp b/Telegram/SourceFiles/ui/boxes/boost_box.cpp index 0486d0cc3..008726ee6 100644 --- a/Telegram/SourceFiles/ui/boxes/boost_box.cpp +++ b/Telegram/SourceFiles/ui/boxes/boost_box.cpp @@ -678,17 +678,18 @@ void AskBoostBox( box->addTopButton(st::boxTitleClose, [=] { box->closeBox(); }); - auto title = v::match(data.reason.data, [&]( - AskBoostChannelColor data) { + auto title = v::match(data.reason.data, [](AskBoostChannelColor) { return tr::lng_boost_channel_title_color(); - }, [&](AskBoostWallpaper data) { + }, [](AskBoostWallpaper) { return tr::lng_boost_channel_title_wallpaper(); - }, [&](AskBoostEmojiStatus data) { + }, [](AskBoostEmojiStatus) { return tr::lng_boost_channel_title_status(); - }, [&](AskBoostEmojiPack data) { + }, [](AskBoostEmojiPack) { return tr::lng_boost_group_title_emoji(); - }, [&](AskBoostCustomReactions data) { + }, [](AskBoostCustomReactions) { return tr::lng_boost_channel_title_reactions(); + }, [](AskBoostCpm) { + return tr::lng_boost_channel_title_cpm(); }); auto reasonText = v::match(data.reason.data, [&]( AskBoostChannelColor data) { @@ -722,6 +723,11 @@ void AskBoostBox( lt_same_count, rpl::single(TextWithEntities{ QString::number(data.count) }), Ui::Text::RichLangValue); + }, [&](AskBoostCpm data) { + return tr::lng_boost_channel_needs_level_cpm( + lt_count, + rpl::single(float64(data.requiredLevel)), + Ui::Text::RichLangValue); }); auto text = rpl::combine( std::move(reasonText), diff --git a/Telegram/SourceFiles/ui/boxes/boost_box.h b/Telegram/SourceFiles/ui/boxes/boost_box.h index 78e046cba..ecac121b9 100644 --- a/Telegram/SourceFiles/ui/boxes/boost_box.h +++ b/Telegram/SourceFiles/ui/boxes/boost_box.h @@ -89,13 +89,18 @@ struct AskBoostCustomReactions { int count = 0; }; +struct AskBoostCpm { + int requiredLevel = 0; +}; + struct AskBoostReason { std::variant< AskBoostChannelColor, AskBoostWallpaper, AskBoostEmojiStatus, AskBoostEmojiPack, - AskBoostCustomReactions> data; + AskBoostCustomReactions, + AskBoostCpm> data; }; struct AskBoostBoxData {