mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Set custom reactions hard limit to max level.
This commit is contained in:
parent
514ced1d8e
commit
2611899448
6 changed files with 54 additions and 9 deletions
|
@ -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_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" = "Boost your channel {link}.";
|
||||||
"lng_manage_peer_reactions_boost_link" = "here";
|
"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" = "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.";
|
"lng_manage_peer_antispam_about" = "Telegram will filter more spam but may occasionally affect ordinary messages. You can report False Positives in Recent Actions.";
|
||||||
|
|
|
@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_message_reactions.h"
|
#include "data/data_message_reactions.h"
|
||||||
#include "data/data_peer_values.h"
|
#include "data/data_peer_values.h"
|
||||||
|
#include "data/data_premium_limits.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "history/admin_log/history_admin_log_section.h"
|
#include "history/admin_log/history_admin_log_section.h"
|
||||||
#include "info/boosts/info_boosts_widget.h"
|
#include "info/boosts/info_boosts_widget.h"
|
||||||
|
@ -1315,6 +1316,8 @@ void Controller::editReactions() {
|
||||||
EditAllowedReactionsArgs{
|
EditAllowedReactionsArgs{
|
||||||
.navigation = _navigation,
|
.navigation = _navigation,
|
||||||
.allowedCustomReactions = counters.level,
|
.allowedCustomReactions = counters.level,
|
||||||
|
.customReactionsHardLimit = Data::PremiumLimits(
|
||||||
|
&_peer->session()).maxBoostLevel(),
|
||||||
.list = _navigation->session().data().reactions().list(
|
.list = _navigation->session().data().reactions().list(
|
||||||
Data::Reactions::Type::Active),
|
Data::Reactions::Type::Active),
|
||||||
.allowed = Data::PeerAllowedReactions(_peer),
|
.allowed = Data::PeerAllowedReactions(_peer),
|
||||||
|
|
|
@ -42,6 +42,10 @@ constexpr auto kDisabledEmojiOpacity = 0.4;
|
||||||
|
|
||||||
struct UniqueCustomEmojiContext {
|
struct UniqueCustomEmojiContext {
|
||||||
std::vector<DocumentId> ids;
|
std::vector<DocumentId> ids;
|
||||||
|
Fn<bool(DocumentId)> applyHardLimit;
|
||||||
|
int hardLimit = 0;
|
||||||
|
int hardLimitChecked = 0;
|
||||||
|
bool hardLimitHit = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MaybeDisabledEmoji final : public Ui::Text::CustomEmoji {
|
class MaybeDisabledEmoji final : public Ui::Text::CustomEmoji {
|
||||||
|
@ -153,6 +157,7 @@ bool MaybeDisabledEmoji::readyInDefaultState() {
|
||||||
not_null<QTextDocument*> document,
|
not_null<QTextDocument*> document,
|
||||||
UniqueCustomEmojiContext &context) {
|
UniqueCustomEmojiContext &context) {
|
||||||
context.ids.clear();
|
context.ids.clear();
|
||||||
|
context.hardLimitChecked = 0;
|
||||||
auto removeFrom = 0;
|
auto removeFrom = 0;
|
||||||
auto removeTill = 0;
|
auto removeTill = 0;
|
||||||
auto block = document->begin();
|
auto block = document->begin();
|
||||||
|
@ -168,11 +173,20 @@ bool MaybeDisabledEmoji::readyInDefaultState() {
|
||||||
}
|
}
|
||||||
const auto id = format.property(Ui::InputField::kCustomEmojiId);
|
const auto id = format.property(Ui::InputField::kCustomEmojiId);
|
||||||
const auto documentId = id.toULongLong();
|
const auto documentId = id.toULongLong();
|
||||||
|
const auto applyHardLimit = context.applyHardLimit(documentId);
|
||||||
if (ranges::contains(context.ids, documentId)) {
|
if (ranges::contains(context.ids, documentId)) {
|
||||||
removeTill += fragment.length();
|
removeTill += fragment.length();
|
||||||
break;
|
break;
|
||||||
|
} else if (applyHardLimit
|
||||||
|
&& context.hardLimitChecked >= context.hardLimit) {
|
||||||
|
context.hardLimitHit = true;
|
||||||
|
removeTill += fragment.length();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
context.ids.push_back(documentId);
|
context.ids.push_back(documentId);
|
||||||
|
if (applyHardLimit) {
|
||||||
|
++context.hardLimitChecked;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (removeTill == removeFrom) {
|
while (removeTill == removeFrom) {
|
||||||
block = block.next();
|
block = block.next();
|
||||||
|
@ -202,7 +216,9 @@ bool RemoveNonCustomEmoji(
|
||||||
|
|
||||||
void SetupOnlyCustomEmojiField(
|
void SetupOnlyCustomEmojiField(
|
||||||
not_null<Ui::InputField*> field,
|
not_null<Ui::InputField*> field,
|
||||||
Fn<void(std::vector<DocumentId>)> callback) {
|
Fn<void(std::vector<DocumentId>, bool)> callback,
|
||||||
|
Fn<bool(DocumentId)> applyHardLimit,
|
||||||
|
int customHardLimit) {
|
||||||
field->setTagMimeProcessor(AllowOnlyCustomEmojiProcessor);
|
field->setTagMimeProcessor(AllowOnlyCustomEmojiProcessor);
|
||||||
field->setMimeDataHook(AllowOnlyCustomEmojiMimeDataHook);
|
field->setMimeDataHook(AllowOnlyCustomEmojiMimeDataHook);
|
||||||
|
|
||||||
|
@ -218,7 +234,10 @@ void SetupOnlyCustomEmojiField(
|
||||||
if (state->processing) {
|
if (state->processing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto context = UniqueCustomEmojiContext();
|
auto context = UniqueCustomEmojiContext{
|
||||||
|
.applyHardLimit = applyHardLimit,
|
||||||
|
.hardLimit = customHardLimit,
|
||||||
|
};
|
||||||
auto changed = false;
|
auto changed = false;
|
||||||
state->processing = true;
|
state->processing = true;
|
||||||
while (state->pending) {
|
while (state->pending) {
|
||||||
|
@ -235,7 +254,7 @@ void SetupOnlyCustomEmojiField(
|
||||||
document->setPageSize(pageSize);
|
document->setPageSize(pageSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callback(context.ids);
|
callback(context.ids, context.hardLimitHit);
|
||||||
if (changed) {
|
if (changed) {
|
||||||
field->forceProcessContentsChanges();
|
field->forceProcessContentsChanges();
|
||||||
}
|
}
|
||||||
|
@ -289,9 +308,10 @@ struct ReactionsSelectorArgs {
|
||||||
rpl::producer<QString> title;
|
rpl::producer<QString> title;
|
||||||
std::vector<Data::Reaction> list;
|
std::vector<Data::Reaction> list;
|
||||||
std::vector<Data::ReactionId> selected;
|
std::vector<Data::ReactionId> selected;
|
||||||
Fn<void(std::vector<Data::ReactionId>)> callback;
|
Fn<void(std::vector<Data::ReactionId>, bool)> callback;
|
||||||
rpl::producer<ReactionsSelectorState> stateValue;
|
rpl::producer<ReactionsSelectorState> stateValue;
|
||||||
int customAllowed = 0;
|
int customAllowed = 0;
|
||||||
|
int customHardLimit = 0;
|
||||||
bool all = false;
|
bool all = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -344,7 +364,12 @@ object_ptr<Ui::RpWidget> AddReactionsSelector(
|
||||||
}, std::move(customEmojiPaused));
|
}, std::move(customEmojiPaused));
|
||||||
|
|
||||||
const auto callback = args.callback;
|
const auto callback = args.callback;
|
||||||
SetupOnlyCustomEmojiField(raw, [=](std::vector<DocumentId> ids) {
|
const auto isCustom = [=](DocumentId id) {
|
||||||
|
return state->unifiedFactoryOwner->lookupReactionId(id).custom();
|
||||||
|
};
|
||||||
|
SetupOnlyCustomEmojiField(raw, [=](
|
||||||
|
std::vector<DocumentId> ids,
|
||||||
|
bool hardLimitHit) {
|
||||||
auto allowed = base::flat_set<DocumentId>();
|
auto allowed = base::flat_set<DocumentId>();
|
||||||
auto reactions = std::vector<Data::ReactionId>();
|
auto reactions = std::vector<Data::ReactionId>();
|
||||||
reactions.reserve(ids.size());
|
reactions.reserve(ids.size());
|
||||||
|
@ -361,8 +386,8 @@ object_ptr<Ui::RpWidget> AddReactionsSelector(
|
||||||
state->allowed = std::move(allowed);
|
state->allowed = std::move(allowed);
|
||||||
raw->rawTextEdit()->update();
|
raw->rawTextEdit()->update();
|
||||||
}
|
}
|
||||||
callback(std::move(reactions));
|
callback(std::move(reactions), hardLimitHit);
|
||||||
});
|
}, isCustom, args.customHardLimit);
|
||||||
raw->setTextWithTags(ComposeEmojiList(reactions, args.selected));
|
raw->setTextWithTags(ComposeEmojiList(reactions, args.selected));
|
||||||
|
|
||||||
using SelectorState = ReactionsSelectorState;
|
using SelectorState = ReactionsSelectorState;
|
||||||
|
@ -667,13 +692,19 @@ void EditAllowedReactionsBox(
|
||||||
| ranges::views::transform(&Data::Reaction::id)
|
| ranges::views::transform(&Data::Reaction::id)
|
||||||
| ranges::to_vector)
|
| ranges::to_vector)
|
||||||
: allowed.some;
|
: allowed.some;
|
||||||
const auto changed = [=](std::vector<Data::ReactionId> chosen) {
|
const auto changed = [=](
|
||||||
|
std::vector<Data::ReactionId> chosen,
|
||||||
|
bool hardLimitHit) {
|
||||||
state->selected = std::move(chosen);
|
state->selected = std::move(chosen);
|
||||||
state->customCount = ranges::count_if(
|
state->customCount = ranges::count_if(
|
||||||
state->selected,
|
state->selected,
|
||||||
&Data::ReactionId::custom);
|
&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, {
|
reactions->add(AddReactionsSelector(reactions, {
|
||||||
.outer = box->getDelegate()->outerContainer(),
|
.outer = box->getDelegate()->outerContainer(),
|
||||||
.controller = args.navigation->parentController(),
|
.controller = args.navigation->parentController(),
|
||||||
|
@ -685,6 +716,7 @@ void EditAllowedReactionsBox(
|
||||||
.callback = changed,
|
.callback = changed,
|
||||||
.stateValue = state->selectorState.value(),
|
.stateValue = state->selectorState.value(),
|
||||||
.customAllowed = args.allowedCustomReactions,
|
.customAllowed = args.allowedCustomReactions,
|
||||||
|
.customHardLimit = args.customReactionsHardLimit,
|
||||||
.all = !args.isGroup,
|
.all = !args.isGroup,
|
||||||
}), st::boxRowPadding);
|
}), st::boxRowPadding);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ class SessionNavigation;
|
||||||
struct EditAllowedReactionsArgs {
|
struct EditAllowedReactionsArgs {
|
||||||
not_null<Window::SessionNavigation*> navigation;
|
not_null<Window::SessionNavigation*> navigation;
|
||||||
int allowedCustomReactions = 0;
|
int allowedCustomReactions = 0;
|
||||||
|
int customReactionsHardLimit = 0;
|
||||||
bool isGroup = false;
|
bool isGroup = false;
|
||||||
std::vector<Data::Reaction> list;
|
std::vector<Data::Reaction> list;
|
||||||
Data::AllowedReactions allowed;
|
Data::AllowedReactions allowed;
|
||||||
|
|
|
@ -189,6 +189,12 @@ int PremiumLimits::aboutLengthCurrent() const {
|
||||||
: aboutLengthDefault();
|
: aboutLengthDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PremiumLimits::maxBoostLevel() const {
|
||||||
|
return appConfigLimit(
|
||||||
|
u"boosts_channel_level_max"_q,
|
||||||
|
_session->isTestMode() ? 9 : 99);
|
||||||
|
}
|
||||||
|
|
||||||
int PremiumLimits::appConfigLimit(
|
int PremiumLimits::appConfigLimit(
|
||||||
const QString &key,
|
const QString &key,
|
||||||
int fallback) const {
|
int fallback) const {
|
||||||
|
|
|
@ -75,6 +75,8 @@ public:
|
||||||
[[nodiscard]] int aboutLengthPremium() const;
|
[[nodiscard]] int aboutLengthPremium() const;
|
||||||
[[nodiscard]] int aboutLengthCurrent() const;
|
[[nodiscard]] int aboutLengthCurrent() const;
|
||||||
|
|
||||||
|
[[nodiscard]] int maxBoostLevel() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] int appConfigLimit(
|
[[nodiscard]] int appConfigLimit(
|
||||||
const QString &key,
|
const QString &key,
|
||||||
|
|
Loading…
Add table
Reference in a new issue