From df16e7c00bc3ea56fe405e5649a0e5f7fff3fa7a Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 16 Apr 2024 04:35:46 +0300 Subject: [PATCH] Added ability to change reactions limit in channels. --- Telegram/Resources/langs/lang.strings | 6 + .../boxes/peers/edit_peer_reactions.cpp | 139 ++++++++++++++++-- Telegram/SourceFiles/info/info.style | 16 +- 3 files changed, 144 insertions(+), 17 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index f31460e4ed..c727d4c5eb 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1495,6 +1495,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_manage_peer_reactions_none_about" = "Members of the group can't add any reactions to messages."; "lng_manage_peer_reactions_some_title" = "Only allow these reactions"; "lng_manage_peer_reactions_available" = "Available reactions"; +"lng_manage_peer_reactions_available_ph" = "Add reactions..."; "lng_manage_peer_reactions_own" = "You can also {link} emoji packs and use them as reactions."; "lng_manage_peer_reactions_own_link" = "create your own"; "lng_manage_peer_reactions_level#one" = "Your channel needs to reach level **{count}** to use **{same_count}** custom reaction."; @@ -1503,6 +1504,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_manage_peer_reactions_boost_link" = "here"; "lng_manage_peer_reactions_limit" = "Channels can't have more custom reactions."; +"lng_manage_peer_reactions_max_title" = "Maximum number of reactions"; +"lng_manage_peer_reactions_max_slider#one" = "{count} reaction per post"; +"lng_manage_peer_reactions_max_slider#other" = "{count} reactions per post"; +"lng_manage_peer_reactions_max_about" = "Limit the number of different reactions that can be added to a post, including already published ones."; + "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_not_enough#one" = "Aggressive filtering can be enabled only in groups with more than **{count} member**."; diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp index 71430ace09..0873426e52 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp @@ -7,30 +7,33 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/peers/edit_peer_reactions.h" +#include "apiwrap.h" #include "base/event_filter.h" #include "chat_helpers/tabbed_panel.h" #include "chat_helpers/tabbed_selector.h" -#include "data/data_chat.h" #include "data/data_channel.h" +#include "data/data_chat.h" #include "data/data_document.h" +#include "data/data_peer_values.h" // UniqueReactionsLimit. #include "data/data_session.h" +#include "data/data_user.h" #include "history/view/reactions/history_view_reactions_selector.h" -#include "main/main_session.h" -#include "apiwrap.h" #include "lang/lang_keys.h" +#include "main/main_session.h" #include "ui/boxes/boost_box.h" -#include "ui/widgets/fields/input_field.h" #include "ui/layers/generic_box.h" #include "ui/text/text_utilities.h" -#include "ui/widgets/checkbox.h" -#include "ui/wrap/slide_wrap.h" #include "ui/vertical_list.h" +#include "ui/widgets/checkbox.h" +#include "ui/widgets/continuous_sliders.h" +#include "ui/widgets/fields/input_field.h" +#include "ui/wrap/slide_wrap.h" #include "window/window_session_controller.h" #include "window/window_session_controller_link_info.h" #include "styles/style_chat_helpers.h" #include "styles/style_info.h" -#include "styles/style_settings.h" #include "styles/style_layers.h" +#include "styles/style_settings.h" #include #include @@ -705,12 +708,16 @@ void EditAllowedReactionsBox( } }; changed(selected.empty() ? DefaultSelected() : std::move(selected), {}); + Ui::AddSubsectionTitle( + reactions, + enabled + ? tr::lng_manage_peer_reactions_available() + : tr::lng_manage_peer_reactions_some_title(), + st::manageGroupReactionsFieldPadding); reactions->add(AddReactionsSelector(reactions, { .outer = box->getDelegate()->outerContainer(), .controller = args.navigation->parentController(), - .title = (enabled - ? tr::lng_manage_peer_reactions_available() - : tr::lng_manage_peer_reactions_some_title()), + .title = tr::lng_manage_peer_reactions_available_ph(), .list = all, .selected = state->selected, .callback = changed, @@ -726,6 +733,7 @@ void EditAllowedReactionsBox( } }); + const auto reactionsLimit = container->lifetime().make_state(0); if (!isGroup) { AddReactionsText( container, @@ -733,9 +741,109 @@ void EditAllowedReactionsBox( args.allowedCustomReactions, state->customCount.value(), args.askForBoosts); + + const auto session = &args.navigation->parentController()->session(); + + const auto wrap = container->add( + object_ptr>( + container, + object_ptr(container))); + const auto max = Data::UniqueReactionsLimit(session->user()); + const auto inactiveColor = std::make_optional(st::windowSubTextFg->c); + const auto activeColor = std::make_optional( + st::windowActiveTextFg->c); + const auto inner = wrap->entity(); + Ui::AddSkip(inner); + Ui::AddSubsectionTitle( + inner, + tr::lng_manage_peer_reactions_max_title(), + st::manageGroupReactionsMaxSubtitlePadding); + Ui::AddSkip(inner); + const auto line = inner->add( + object_ptr(inner), + st::boxRowPadding); + Ui::AddSkip(inner); + Ui::AddSkip(inner); + const auto left = Ui::CreateChild( + line, + QString::number(1), + st::defaultFlatLabel); + const auto center = Ui::CreateChild( + line, + st::defaultFlatLabel); + const auto right = Ui::CreateChild( + line, + QString::number(max), + st::defaultFlatLabel); + 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 * 1.5, + r.width(), + sliderHeight); + } + left->moveToLeft(0, 0); + right->moveToRight(0, 0); + center->moveToLeft((s.width() - centerSize.width()) / 2, 0); + }, line->lifetime()); + + const auto updateLabels = [=](int limit) { + left->setTextColorOverride((limit <= 1) + ? activeColor + : inactiveColor); + + center->setText(tr::lng_manage_peer_reactions_max_slider( + tr::now, + lt_count, + limit)); + center->setTextColorOverride(activeColor); + + right->setTextColorOverride((limit >= max) + ? activeColor + : inactiveColor); + + (*reactionsLimit) = limit; + }; + const auto current = args.allowed.maxCount + ? std::clamp(1, args.allowed.maxCount, max) + : max / 2; + slider->setPseudoDiscrete( + max, + [=](int index) { return index + 1; }, + current, + updateLabels, + updateLabels); + updateLabels(current); + + wrap->toggleOn(rpl::single( + optionInitial != Option::None + ) | rpl::then( + state->selectorState.value( + ) | rpl::map(rpl::mappers::_1 == SelectorState::Active))); + + Ui::AddDividerText(inner, tr::lng_manage_peer_reactions_max_about()); } const auto collect = [=] { auto result = AllowedReactions(); + result.maxCount = (*reactionsLimit); if (isGroup ? (state->option.current() == Option::Some) : (enabled->toggled())) { @@ -783,6 +891,7 @@ void SaveAllowedReactions( Data::ReactionToMTP ) | ranges::to>; + using Flag = MTPmessages_SetChatAvailableReactions::Flag; using Type = Data::AllowedReactionsType; const auto updated = (allowed.type != Type::Some) ? MTP_chatReactionsAll(MTP_flags((allowed.type == Type::Default) @@ -792,16 +901,18 @@ void SaveAllowedReactions( ? MTP_chatReactionsNone() : MTP_chatReactionsSome(MTP_vector(ids)); peer->session().api().request(MTPmessages_SetChatAvailableReactions( - MTP_flags(0), + allowed.maxCount ? MTP_flags(Flag::f_reactions_limit) : MTP_flags(0), peer->input, updated, - MTP_int(0) // reactions_limit + MTP_int(allowed.maxCount) )).done([=](const MTPUpdates &result) { peer->session().api().applyUpdates(result); + auto parsed = Data::Parse(updated); + parsed.maxCount = allowed.maxCount; if (const auto chat = peer->asChat()) { - chat->setAllowedReactions(Data::Parse(updated)); + chat->setAllowedReactions(parsed); } else if (const auto channel = peer->asChannel()) { - channel->setAllowedReactions(Data::Parse(updated)); + channel->setAllowedReactions(parsed); } else { Unexpected("Invalid peer type in SaveAllowedReactions."); } diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index d59de8526b..cf6f410cd4 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -647,12 +647,22 @@ manageGroupReactions: IconButton(defaultIconButton) { iconOver: icon{{ "info/edit/stickers_add", historyComposeIconFgOver }}; } manageGroupReactionsField: InputField(defaultInputField) { - textMargins: margins(1px, 38px, 24px, 8px); - placeholderShift: -32px; - heightMin: 66px; + textMargins: margins(1px, 12px, 24px, 8px); + placeholderFg: placeholderFg; + placeholderFgActive: placeholderFgActive; + placeholderFgError: placeholderFgActive; + placeholderMargins: margins(1px, 0px, 7px, 0px); + placeholderAlign: align(topleft); + placeholderScale: 0.; + placeholderFont: normalFont; + placeholderShift: -50px; + font: normalFont; + heightMin: 36px; heightMax: 158px; } +manageGroupReactionsFieldPadding: margins(0px, 0px, 0px, -9px); manageGroupReactionsTextSkip: 16px; +manageGroupReactionsMaxSubtitlePadding: margins(0px, 0px, 0px, -3px); infoEmptyFg: windowSubTextFg; infoEmptyPhoto: icon {{ "info/info_media_photo_empty", infoEmptyFg }};