From 2611899448b78081ab273ffb5ae5da38715cb495 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 29 Nov 2023 18:25:27 +0400 Subject: [PATCH] Set custom reactions hard limit to max level. --- Telegram/Resources/langs/lang.strings | 1 + .../boxes/peers/edit_peer_info_box.cpp | 3 ++ .../boxes/peers/edit_peer_reactions.cpp | 50 +++++++++++++++---- .../boxes/peers/edit_peer_reactions.h | 1 + .../SourceFiles/data/data_premium_limits.cpp | 6 +++ .../SourceFiles/data/data_premium_limits.h | 2 + 6 files changed, 54 insertions(+), 9 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 4df401e10..c7160a2a3 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1357,6 +1357,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_manage_peer_reactions_level#other" = "Your channel needs to reach level **{count}** to use **{same_count}** custom reactions."; "lng_manage_peer_reactions_boost" = "Boost your channel {link}."; "lng_manage_peer_reactions_boost_link" = "here"; +"lng_manage_peer_reactions_limit" = "Channels can't have more custom reactions."; "lng_manage_peer_antispam" = "Aggressive Anti-Spam"; "lng_manage_peer_antispam_about" = "Telegram will filter more spam but may occasionally affect ordinary messages. You can report False Positives in Recent Actions."; diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 8f81f0cc0..1e5a895dd 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_changes.h" #include "data/data_message_reactions.h" #include "data/data_peer_values.h" +#include "data/data_premium_limits.h" #include "data/data_user.h" #include "history/admin_log/history_admin_log_section.h" #include "info/boosts/info_boosts_widget.h" @@ -1315,6 +1316,8 @@ void Controller::editReactions() { EditAllowedReactionsArgs{ .navigation = _navigation, .allowedCustomReactions = counters.level, + .customReactionsHardLimit = Data::PremiumLimits( + &_peer->session()).maxBoostLevel(), .list = _navigation->session().data().reactions().list( Data::Reactions::Type::Active), .allowed = Data::PeerAllowedReactions(_peer), diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp index dd5bc8d79..fddad6fc0 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp @@ -42,6 +42,10 @@ constexpr auto kDisabledEmojiOpacity = 0.4; struct UniqueCustomEmojiContext { std::vector ids; + Fn applyHardLimit; + int hardLimit = 0; + int hardLimitChecked = 0; + bool hardLimitHit = false; }; class MaybeDisabledEmoji final : public Ui::Text::CustomEmoji { @@ -153,6 +157,7 @@ bool MaybeDisabledEmoji::readyInDefaultState() { not_null document, UniqueCustomEmojiContext &context) { context.ids.clear(); + context.hardLimitChecked = 0; auto removeFrom = 0; auto removeTill = 0; auto block = document->begin(); @@ -168,11 +173,20 @@ bool MaybeDisabledEmoji::readyInDefaultState() { } const auto id = format.property(Ui::InputField::kCustomEmojiId); const auto documentId = id.toULongLong(); + const auto applyHardLimit = context.applyHardLimit(documentId); if (ranges::contains(context.ids, documentId)) { removeTill += fragment.length(); break; + } else if (applyHardLimit + && context.hardLimitChecked >= context.hardLimit) { + context.hardLimitHit = true; + removeTill += fragment.length(); + break; } context.ids.push_back(documentId); + if (applyHardLimit) { + ++context.hardLimitChecked; + } } while (removeTill == removeFrom) { block = block.next(); @@ -202,7 +216,9 @@ bool RemoveNonCustomEmoji( void SetupOnlyCustomEmojiField( not_null field, - Fn)> callback) { + Fn, bool)> callback, + Fn applyHardLimit, + int customHardLimit) { field->setTagMimeProcessor(AllowOnlyCustomEmojiProcessor); field->setMimeDataHook(AllowOnlyCustomEmojiMimeDataHook); @@ -218,7 +234,10 @@ void SetupOnlyCustomEmojiField( if (state->processing) { return; } - auto context = UniqueCustomEmojiContext(); + auto context = UniqueCustomEmojiContext{ + .applyHardLimit = applyHardLimit, + .hardLimit = customHardLimit, + }; auto changed = false; state->processing = true; while (state->pending) { @@ -235,7 +254,7 @@ void SetupOnlyCustomEmojiField( document->setPageSize(pageSize); } } - callback(context.ids); + callback(context.ids, context.hardLimitHit); if (changed) { field->forceProcessContentsChanges(); } @@ -289,9 +308,10 @@ struct ReactionsSelectorArgs { rpl::producer title; std::vector list; std::vector selected; - Fn)> callback; + Fn, bool)> callback; rpl::producer stateValue; int customAllowed = 0; + int customHardLimit = 0; bool all = false; }; @@ -344,7 +364,12 @@ object_ptr AddReactionsSelector( }, std::move(customEmojiPaused)); const auto callback = args.callback; - SetupOnlyCustomEmojiField(raw, [=](std::vector ids) { + const auto isCustom = [=](DocumentId id) { + return state->unifiedFactoryOwner->lookupReactionId(id).custom(); + }; + SetupOnlyCustomEmojiField(raw, [=]( + std::vector ids, + bool hardLimitHit) { auto allowed = base::flat_set(); auto reactions = std::vector(); reactions.reserve(ids.size()); @@ -361,8 +386,8 @@ object_ptr AddReactionsSelector( state->allowed = std::move(allowed); raw->rawTextEdit()->update(); } - callback(std::move(reactions)); - }); + callback(std::move(reactions), hardLimitHit); + }, isCustom, args.customHardLimit); raw->setTextWithTags(ComposeEmojiList(reactions, args.selected)); using SelectorState = ReactionsSelectorState; @@ -667,13 +692,19 @@ void EditAllowedReactionsBox( | ranges::views::transform(&Data::Reaction::id) | ranges::to_vector) : allowed.some; - const auto changed = [=](std::vector chosen) { + const auto changed = [=]( + std::vector chosen, + bool hardLimitHit) { state->selected = std::move(chosen); state->customCount = ranges::count_if( state->selected, &Data::ReactionId::custom); + if (hardLimitHit) { + box->uiShow()->showToast( + tr::lng_manage_peer_reactions_limit(tr::now)); + } }; - changed(selected.empty() ? DefaultSelected() : std::move(selected)); + changed(selected.empty() ? DefaultSelected() : std::move(selected), {}); reactions->add(AddReactionsSelector(reactions, { .outer = box->getDelegate()->outerContainer(), .controller = args.navigation->parentController(), @@ -685,6 +716,7 @@ void EditAllowedReactionsBox( .callback = changed, .stateValue = state->selectorState.value(), .customAllowed = args.allowedCustomReactions, + .customHardLimit = args.customReactionsHardLimit, .all = !args.isGroup, }), st::boxRowPadding); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.h b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.h index 642a04cde..ae5c1638f 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.h +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.h @@ -25,6 +25,7 @@ class SessionNavigation; struct EditAllowedReactionsArgs { not_null navigation; int allowedCustomReactions = 0; + int customReactionsHardLimit = 0; bool isGroup = false; std::vector list; Data::AllowedReactions allowed; diff --git a/Telegram/SourceFiles/data/data_premium_limits.cpp b/Telegram/SourceFiles/data/data_premium_limits.cpp index 0f0d495b8..07a5124a6 100644 --- a/Telegram/SourceFiles/data/data_premium_limits.cpp +++ b/Telegram/SourceFiles/data/data_premium_limits.cpp @@ -189,6 +189,12 @@ int PremiumLimits::aboutLengthCurrent() const { : aboutLengthDefault(); } +int PremiumLimits::maxBoostLevel() const { + return appConfigLimit( + u"boosts_channel_level_max"_q, + _session->isTestMode() ? 9 : 99); +} + int PremiumLimits::appConfigLimit( const QString &key, int fallback) const { diff --git a/Telegram/SourceFiles/data/data_premium_limits.h b/Telegram/SourceFiles/data/data_premium_limits.h index 079f214e6..f9bd416d2 100644 --- a/Telegram/SourceFiles/data/data_premium_limits.h +++ b/Telegram/SourceFiles/data/data_premium_limits.h @@ -75,6 +75,8 @@ public: [[nodiscard]] int aboutLengthPremium() const; [[nodiscard]] int aboutLengthCurrent() const; + [[nodiscard]] int maxBoostLevel() const; + private: [[nodiscard]] int appConfigLimit( const QString &key,