diff --git a/Telegram/Resources/tl/api.tl b/Telegram/Resources/tl/api.tl index b1e0b5620..19e71f0ec 100644 --- a/Telegram/Resources/tl/api.tl +++ b/Telegram/Resources/tl/api.tl @@ -128,8 +128,8 @@ chatForbidden#6592a1a7 id:long title:string = Chat; channel#8261ac61 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat; channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat; -chatFull#d18ee226 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector available_reactions:flags.18?Vector = ChatFull; -channelFull#ea68a619 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?Vector = ChatFull; +chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector available_reactions:flags.18?ChatReactions = ChatFull; +channelFull#f2355507 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions = ChatFull; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; @@ -1417,6 +1417,10 @@ reactionEmpty#79f5d419 = Reaction; reactionEmoji#1b2286b8 emoticon:string = Reaction; reactionCustomEmoji#8935fc73 document_id:long = Reaction; +chatReactionsNone#eafc32bc = ChatReactions; +chatReactionsAll#52928bca flags:# allow_custom:flags.0?true = ChatReactions; +chatReactionsSome#661d4037 reactions:Vector = ChatReactions; + emailVerifyPurposeLoginSetup#4345be73 phone_number:string phone_code_hash:string = EmailVerifyPurpose; emailVerifyPurposeLoginChange#527d22eb = EmailVerifyPurpose; emailVerifyPurposePassport#bbf51685 = EmailVerifyPurpose; @@ -1716,7 +1720,7 @@ messages.saveDefaultSendAs#ccfddf96 peer:InputPeer send_as:InputPeer = Bool; messages.sendReaction#d30d78d4 flags:# big:flags.1?true peer:InputPeer msg_id:int reaction:flags.0?Vector = Updates; messages.getMessagesReactions#8bba90e6 peer:InputPeer id:Vector = Updates; messages.getMessageReactionsList#461b3f48 flags:# peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = messages.MessageReactionsList; -messages.setChatAvailableReactions#14050ea6 peer:InputPeer available_reactions:Vector = Updates; +messages.setChatAvailableReactions#feb16771 peer:InputPeer available_reactions:ChatReactions = Updates; messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions; messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool; messages.translateText#24ce6dee flags:# peer:flags.0?InputPeer msg_id:flags.0?int text:flags.1?string from_lang:flags.2?string to_lang:string = messages.TranslatedText; diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 9779cde58..606e50524 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -1002,8 +1002,8 @@ void Controller::fillManageSection() { ? QString::number(allowed) + " / " + QString::number(total) : tr::lng_manage_peer_reactions_off(tr::now); }); - const auto done = [=](const std::vector &chosen) { - SaveAllowedReactions(_peer, chosen); + const auto done = [=](const std::vector &chosen, bool all) { + SaveAllowedReactions(_peer, chosen, all); }; AddButtonWithCount( _controls.buttonsLayout, @@ -1015,7 +1015,7 @@ void Controller::fillManageSection() { !_peer->isBroadcast(), session->data().reactions().list( Data::Reactions::Type::Active), - *Data::PeerReactionsFilter(_peer).allowed, + Data::PeerAllowedReactions(_peer), done)); }, { &st::infoRoundedIconReactions, Settings::kIconRed }); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp index 75083f3b0..fe47eb4e4 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.cpp @@ -26,8 +26,8 @@ void EditAllowedReactionsBox( not_null box, bool isGroup, const std::vector &list, - const base::flat_set &selected, - Fn &)> callback) { + const Data::AllowedReactions &allowed, + Fn &, bool all)> callback) { const auto iconHeight = st::editPeerReactionsPreview; box->setTitle(tr::lng_manage_peer_reactions()); @@ -37,7 +37,7 @@ void EditAllowedReactionsBox( rpl::event_stream forceToggleAll; }; const auto state = box->lifetime().make_state(State{ - .anyToggled = !selected.empty(), + .anyToggled = (allowed.type != Data::AllowedReactionsType::Some), }); const auto collect = [=] { @@ -91,7 +91,7 @@ void EditAllowedReactionsBox( tr::lng_manage_peer_reactions_available()); const auto active = [&](const Data::Reaction &entry) { - return selected.contains(entry.id.emoji()); + return ranges::contains(allowed.some, entry.id); }; const auto add = [&](const Data::Reaction &entry) { if (entry.id.emoji().isEmpty()) { @@ -139,7 +139,7 @@ void EditAllowedReactionsBox( box->addButton(tr::lng_settings_save(), [=] { const auto ids = collect(); box->closeBox(); - callback(ids); + callback(ids, false); }); box->addButton(tr::lng_cancel(), [=] { box->closeBox(); @@ -148,20 +148,26 @@ void EditAllowedReactionsBox( void SaveAllowedReactions( not_null peer, - const std::vector &allowed) { + const std::vector &allowed, + bool all) { auto ids = allowed | ranges::views::transform([=](QString value) { - return MTP_string(value); - }) | ranges::to>; + return MTP_reactionEmoji(MTP_string(value)); + }) | ranges::to>; + const auto updated = all + ? MTP_chatReactionsAll(MTP_flags(peer->isBroadcast() + ? MTPDchatReactionsAll::Flag(0) + : MTPDchatReactionsAll::Flag::f_allow_custom)) + : MTP_chatReactionsSome(MTP_vector(ids)); peer->session().api().request(MTPmessages_SetChatAvailableReactions( peer->input, - MTP_vector(ids) + updated )).done([=](const MTPUpdates &result) { peer->session().api().applyUpdates(result); if (const auto chat = peer->asChat()) { - chat->setAllowedReactions({ begin(allowed), end(allowed) }); + chat->setAllowedReactions(Data::Parse(updated)); } else if (const auto channel = peer->asChannel()) { - channel->setAllowedReactions({ begin(allowed), end(allowed) }); + channel->setAllowedReactions(Data::Parse(updated)); } else { Unexpected("Invalid peer type in SaveAllowedReactions."); } diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.h b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.h index e8dc6f19d..2e91103c8 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.h +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_reactions.h @@ -11,6 +11,7 @@ class PeerData; namespace Data { struct Reaction; +struct AllowedReactions; } // namespace Data namespace Ui { @@ -21,9 +22,10 @@ void EditAllowedReactionsBox( not_null box, bool isGroup, const std::vector &list, - const base::flat_set &selected, - Fn &)> callback); + const Data::AllowedReactions &allowed, + Fn &, bool all)> callback); void SaveAllowedReactions( not_null peer, - const std::vector &allowed); + const std::vector &allowed, + bool all); diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 1140b8468..d748cf311 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -769,20 +769,23 @@ PeerId ChannelData::groupCallDefaultJoinAs() const { return _callDefaultJoinAs; } -void ChannelData::setAllowedReactions(base::flat_set list) { - if (_allowedReactions != list) { - const auto toggled = (_allowedReactions.empty() != list.empty()); - _allowedReactions = std::move(list); - if (toggled) { - owner().reactions().updateAllInHistory( - this, - !_allowedReactions.empty()); +void ChannelData::setAllowedReactions(Data::AllowedReactions value) { + if (_allowedReactions != value) { + const auto enabled = [](const Data::AllowedReactions &allowed) { + return (allowed.type != Data::AllowedReactionsType::Some) + || !allowed.some.empty(); + }; + const auto was = enabled(_allowedReactions); + _allowedReactions = std::move(value); + const auto now = enabled(_allowedReactions); + if (was != now) { + owner().reactions().updateAllInHistory(this, now); } session().changes().peerUpdated(this, UpdateFlag::Reactions); } } -const base::flat_set &ChannelData::allowedReactions() const { +const Data::AllowedReactions &ChannelData::allowedReactions() const { return _allowedReactions; } @@ -935,8 +938,11 @@ void ApplyChannelUpdate( } } channel->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty())); - channel->setAllowedReactions( - Data::Reactions::ParseAllowed(update.vavailable_reactions())); + if (const auto allowed = update.vavailable_reactions()) { + channel->setAllowedReactions(Data::Parse(*allowed)); + } else { + channel->setAllowedReactions({}); + } channel->fullUpdated(); channel->setPendingRequestsCount( update.vrequests_pending().value_or_empty(), diff --git a/Telegram/SourceFiles/data/data_channel.h b/Telegram/SourceFiles/data/data_channel.h index c895626a8..6d5d84234 100644 --- a/Telegram/SourceFiles/data/data_channel.h +++ b/Telegram/SourceFiles/data/data_channel.h @@ -417,8 +417,8 @@ public: void setGroupCallDefaultJoinAs(PeerId peerId); [[nodiscard]] PeerId groupCallDefaultJoinAs() const; - void setAllowedReactions(base::flat_set list); - [[nodiscard]] const base::flat_set &allowedReactions() const; + void setAllowedReactions(Data::AllowedReactions value); + [[nodiscard]] const Data::AllowedReactions &allowedReactions() const; // Still public data members. uint64 access = 0; @@ -467,7 +467,7 @@ private: QString _inviteLink; std::optional _linkedChat; - base::flat_set _allowedReactions; + Data::AllowedReactions _allowedReactions; std::unique_ptr _call; PeerId _callDefaultJoinAs = 0; diff --git a/Telegram/SourceFiles/data/data_chat.cpp b/Telegram/SourceFiles/data/data_chat.cpp index 6dd5a8852..57512feb8 100644 --- a/Telegram/SourceFiles/data/data_chat.cpp +++ b/Telegram/SourceFiles/data/data_chat.cpp @@ -284,20 +284,23 @@ void ChatData::setPendingRequestsCount( } } -void ChatData::setAllowedReactions(base::flat_set list) { - if (_allowedReactions != list) { - const auto toggled = (_allowedReactions.empty() != list.empty()); - _allowedReactions = std::move(list); - if (toggled) { - owner().reactions().updateAllInHistory( - this, - !_allowedReactions.empty()); +void ChatData::setAllowedReactions(Data::AllowedReactions value) { + if (_allowedReactions != value) { + const auto enabled = [](const Data::AllowedReactions &allowed) { + return (allowed.type != Data::AllowedReactionsType::Some) + || !allowed.some.empty(); + }; + const auto was = enabled(_allowedReactions); + _allowedReactions = std::move(value); + const auto now = enabled(_allowedReactions); + if (was != now) { + owner().reactions().updateAllInHistory(this, now); } session().changes().peerUpdated(this, UpdateFlag::Reactions); } } -const base::flat_set &ChatData::allowedReactions() const { +const Data::AllowedReactions &ChatData::allowedReactions() const { return _allowedReactions; } @@ -475,8 +478,11 @@ void ApplyChatUpdate(not_null chat, const MTPDchatFull &update) { } chat->checkFolder(update.vfolder_id().value_or_empty()); chat->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty())); - chat->setAllowedReactions( - Data::Reactions::ParseAllowed(update.vavailable_reactions())); + if (const auto allowed = update.vavailable_reactions()) { + chat->setAllowedReactions(Data::Parse(*allowed)); + } else { + chat->setAllowedReactions({}); + } chat->fullUpdated(); chat->setAbout(qs(update.vabout())); chat->setPendingRequestsCount( diff --git a/Telegram/SourceFiles/data/data_chat.h b/Telegram/SourceFiles/data/data_chat.h index f75c519bb..5f8558ddb 100644 --- a/Telegram/SourceFiles/data/data_chat.h +++ b/Telegram/SourceFiles/data/data_chat.h @@ -167,8 +167,8 @@ public: int count, std::vector recentRequesters); - void setAllowedReactions(base::flat_set list); - [[nodiscard]] const base::flat_set &allowedReactions() const; + void setAllowedReactions(Data::AllowedReactions value); + [[nodiscard]] const Data::AllowedReactions &allowedReactions() const; // Still public data members. const MTPlong inputChat; @@ -194,7 +194,7 @@ private: int _pendingRequestsCount = 0; std::vector _recentRequesters; - base::flat_set _allowedReactions; + Data::AllowedReactions _allowedReactions; std::unique_ptr _call; PeerId _callDefaultJoinAs = 0; diff --git a/Telegram/SourceFiles/data/data_message_reaction_id.h b/Telegram/SourceFiles/data/data_message_reaction_id.h index c51e2f2c4..f8935e380 100644 --- a/Telegram/SourceFiles/data/data_message_reaction_id.h +++ b/Telegram/SourceFiles/data/data_message_reaction_id.h @@ -37,13 +37,4 @@ inline bool operator==(const ReactionId &a, const ReactionId &b) { [[nodiscard]] ReactionId ReactionFromMTP(const MTPReaction &reaction); [[nodiscard]] MTPReaction ReactionToMTP(ReactionId id); -struct ReactionsFilter { - std::optional> allowed; - bool customAllowed = false; - - friend inline auto operator<=>( - const ReactionsFilter &, - const ReactionsFilter &) = default; -}; - } // namespace Data diff --git a/Telegram/SourceFiles/data/data_message_reactions.cpp b/Telegram/SourceFiles/data/data_message_reactions.cpp index 4bd3f04ad..51077b23a 100644 --- a/Telegram/SourceFiles/data/data_message_reactions.cpp +++ b/Telegram/SourceFiles/data/data_message_reactions.cpp @@ -72,15 +72,14 @@ PossibleItemReactions LookupPossibleReactions(not_null item) { } } } else { - const auto filter = PeerReactionsFilter(peer); - result.recent.reserve(filter.allowed - ? filter.allowed->size() + const auto &allowed = PeerAllowedReactions(peer); + result.recent.reserve((allowed.type == AllowedReactionsType::Some) + ? allowed.some.size() : full.size()); for (const auto &reaction : full) { const auto id = reaction.id; - const auto emoji = filter.allowed ? id.emoji() : QString(); - if (filter.allowed - && (emoji.isEmpty() || !filter.allowed->contains(emoji))) { + if ((allowed.type == AllowedReactionsType::Some) + && !ranges::contains(allowed.some, id)) { continue; } else if (reaction.premium && !session->premium() @@ -93,7 +92,7 @@ PossibleItemReactions LookupPossibleReactions(not_null item) { result.recent.push_back(&reaction); } } - result.customAllowed = session->premium() && peer->isUser(); + result.customAllowed = (allowed.type == AllowedReactionsType::All); } const auto i = ranges::find( result.recent, @@ -344,19 +343,6 @@ void Reactions::downloadTaskFinished() { } } -base::flat_set Reactions::ParseAllowed( - const MTPVector *list) { - if (!list) { - return {}; - } - const auto parsed = ranges::views::all( - list->v - ) | ranges::views::transform([](const MTPstring &string) { - return qs(string); - }) | ranges::to_vector; - return { begin(parsed), end(parsed) }; -} - void Reactions::request() { auto &api = _owner->session().api(); if (_requestId) { diff --git a/Telegram/SourceFiles/data/data_message_reactions.h b/Telegram/SourceFiles/data/data_message_reactions.h index 8dbb3b782..b17701e19 100644 --- a/Telegram/SourceFiles/data/data_message_reactions.h +++ b/Telegram/SourceFiles/data/data_message_reactions.h @@ -61,9 +61,6 @@ public: [[nodiscard]] ReactionId favorite() const; void setFavorite(const ReactionId &emoji); - [[nodiscard]] static base::flat_set ParseAllowed( - const MTPVector *list); - [[nodiscard]] rpl::producer<> updates() const; enum class ImageSize { diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 18433abed..ac5eb77d5 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -109,6 +109,39 @@ bool ApplyBotMenuButton( return changed; } +bool operator<( + const AllowedReactions &a, + const AllowedReactions &b) { + return (a.type < b.type) || ((a.type == b.type) && (a.some < b.some)); +} + +bool operator==( + const AllowedReactions &a, + const AllowedReactions &b) { + return (a.type == b.type) && (a.some == b.some); +} + +AllowedReactions Parse(const MTPChatReactions &value) { + return value.match([&](const MTPDchatReactionsNone &) { + return AllowedReactions(); + }, [&](const MTPDchatReactionsAll &data) { + return AllowedReactions{ + .type = (data.is_allow_custom() + ? AllowedReactionsType::All + : AllowedReactionsType::Default), + }; + }, [&](const MTPDchatReactionsSome &data) { + return AllowedReactions{ + .some = ranges::views::all( + data.vreactions().v + ) | ranges::views::transform( + ReactionFromMTP + ) | ranges::to_vector, + .type = AllowedReactionsType::Some, + }; + }); +} + } // namespace Data PeerClickHandler::PeerClickHandler(not_null peer) diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index 27ec1c03b..483eeb8e7 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -35,6 +35,7 @@ namespace Data { class Session; class GroupCall; class CloudImageView; +struct ReactionId; int PeerColorIndex(PeerId peerId); int PeerColorIndex(BareId bareId); @@ -100,6 +101,22 @@ bool ApplyBotMenuButton( not_null info, const MTPBotMenuButton *button); +enum class AllowedReactionsType { + All, + Default, + Some, +}; + +struct AllowedReactions { + std::vector some; + AllowedReactionsType type = AllowedReactionsType::Some; +}; + +bool operator<(const AllowedReactions &a, const AllowedReactions &b); +bool operator==(const AllowedReactions &a, const AllowedReactions &b); + +[[nodiscard]] AllowedReactions Parse(const MTPChatReactions &value); + } // namespace Data class PeerClickHandler : public ClickHandler { diff --git a/Telegram/SourceFiles/data/data_peer_values.cpp b/Telegram/SourceFiles/data/data_peer_values.cpp index 89f0616f1..8f774a95d 100644 --- a/Telegram/SourceFiles/data/data_peer_values.cpp +++ b/Telegram/SourceFiles/data/data_peer_values.cpp @@ -513,23 +513,26 @@ rpl::producer PeerUserpicImageValue( }; } -ReactionsFilter PeerReactionsFilter(not_null peer) { +const AllowedReactions &PeerAllowedReactions(not_null peer) { if (const auto chat = peer->asChat()) { - return { .allowed = chat->allowedReactions() }; + return chat->allowedReactions(); } else if (const auto channel = peer->asChannel()) { - return { .allowed = channel->allowedReactions() }; + return channel->allowedReactions(); } else { - return { .customAllowed = true }; + static const auto result = AllowedReactions{ + .type = AllowedReactionsType::All, + }; + return result; } } - rpl::producer PeerReactionsFilterValue( + rpl::producer PeerAllowedReactionsValue( not_null peer) { return peer->session().changes().peerFlagsValue( peer, Data::PeerUpdate::Flag::Reactions ) | rpl::map([=]{ - return PeerReactionsFilter(peer); + return PeerAllowedReactions(peer); }); } diff --git a/Telegram/SourceFiles/data/data_peer_values.h b/Telegram/SourceFiles/data/data_peer_values.h index c4c13475f..e4d0b25f0 100644 --- a/Telegram/SourceFiles/data/data_peer_values.h +++ b/Telegram/SourceFiles/data/data_peer_values.h @@ -21,7 +21,6 @@ class Session; namespace Data { struct Reaction; -struct ReactionsFilter; template inline auto FlagsValueWithMask( @@ -134,8 +133,9 @@ inline auto PeerFullFlagValue( int size, ImageRoundRadius radius); -[[nodiscard]] ReactionsFilter PeerReactionsFilter(not_null peer); -[[nodiscard]] rpl::producer PeerReactionsFilterValue( +[[nodiscard]] const AllowedReactions &PeerAllowedReactions( + not_null peer); +[[nodiscard]] rpl::producer PeerAllowedReactionsValue( not_null peer); [[nodiscard]] int UniqueReactionsLimit(not_null peer); diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.h b/Telegram/SourceFiles/history/view/history_view_list_widget.h index 1f50c4b15..61c2bbdbc 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.h +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.h @@ -36,7 +36,7 @@ namespace Data { struct Group; class CloudImageView; struct Reaction; -struct ReactionsFilter; +struct AllowedReactions; } // namespace Data namespace HistoryView::Reactions { @@ -120,7 +120,7 @@ public: } virtual CopyRestrictionType listSelectRestrictionType() = 0; virtual auto listAllowedReactionsValue() - -> rpl::producer = 0; + -> rpl::producer = 0; virtual void listShowPremiumToast(not_null document) = 0; }; diff --git a/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp b/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp index ecee0c3f2..959f4abfa 100644 --- a/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp @@ -684,8 +684,8 @@ CopyRestrictionType PinnedWidget::listSelectRestrictionType() { } auto PinnedWidget::listAllowedReactionsValue() --> rpl::producer { - return Data::PeerReactionsFilterValue(_history->peer); +-> rpl::producer { + return Data::PeerAllowedReactionsValue(_history->peer); } void PinnedWidget::listShowPremiumToast(not_null document) { diff --git a/Telegram/SourceFiles/history/view/history_view_pinned_section.h b/Telegram/SourceFiles/history/view/history_view_pinned_section.h index 9cdf89653..25a7bc617 100644 --- a/Telegram/SourceFiles/history/view/history_view_pinned_section.h +++ b/Telegram/SourceFiles/history/view/history_view_pinned_section.h @@ -106,7 +106,7 @@ public: CopyRestrictionType listCopyRestrictionType(HistoryItem *item) override; CopyRestrictionType listSelectRestrictionType() override; auto listAllowedReactionsValue() - -> rpl::producer override; + -> rpl::producer override; void listShowPremiumToast(not_null document) override; protected: diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 4907fa920..2ab6bd3bb 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -2043,8 +2043,8 @@ CopyRestrictionType RepliesWidget::listSelectRestrictionType() { } auto RepliesWidget::listAllowedReactionsValue() --> rpl::producer { - return Data::PeerReactionsFilterValue(_history->peer); +-> rpl::producer { + return Data::PeerAllowedReactionsValue(_history->peer); } void RepliesWidget::listShowPremiumToast(not_null document) { diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.h b/Telegram/SourceFiles/history/view/history_view_replies_section.h index 9a7469f0c..043197a62 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.h +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.h @@ -143,7 +143,7 @@ public: CopyRestrictionType listCopyRestrictionType(HistoryItem *item) override; CopyRestrictionType listSelectRestrictionType() override; auto listAllowedReactionsValue() - ->rpl::producer override; + ->rpl::producer override; void listShowPremiumToast(not_null document) override; protected: diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index 9d49bd862..aff4ed513 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -1357,9 +1357,8 @@ CopyRestrictionType ScheduledWidget::listSelectRestrictionType() { } auto ScheduledWidget::listAllowedReactionsValue() --> rpl::producer { - const auto empty = base::flat_set(); - return rpl::single(Data::ReactionsFilter{ .allowed = empty }); +-> rpl::producer { + return rpl::single(Data::AllowedReactions()); } void ScheduledWidget::listShowPremiumToast( diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h index 69abc29bd..c321cf35b 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h @@ -128,7 +128,7 @@ public: CopyRestrictionType listCopyRestrictionType(HistoryItem *item) override; CopyRestrictionType listSelectRestrictionType() override; auto listAllowedReactionsValue() - -> rpl::producer override; + -> rpl::producer override; void listShowPremiumToast(not_null document) override; protected: diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp index 46589c16b..133c6cd62 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp @@ -888,7 +888,7 @@ void SetupManagerList( if (peerChanged) { state->peer = peer; state->peerLifetime = rpl::combine( - Data::PeerReactionsFilterValue(peer), + Data::PeerAllowedReactionsValue(peer), Data::UniqueReactionsLimitValue(peer) ) | rpl::start_with_next(push); } else { diff --git a/Telegram/SourceFiles/info/profile/info_profile_values.cpp b/Telegram/SourceFiles/info/profile/info_profile_values.cpp index 3f40faf6d..07e6f1c48 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_values.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_values.cpp @@ -459,16 +459,16 @@ rpl::producer AllowedReactionsCountValue(not_null peer) { if (peer->isUser()) { return FullReactionsCountValue(&peer->session()); } - return peer->session().changes().peerFlagsValue( - peer, - UpdateFlag::Reactions - ) | rpl::map([=] { - if (const auto chat = peer->asChat()) { - return int(chat->allowedReactions().size()); - } else if (const auto channel = peer->asChannel()) { - return int(channel->allowedReactions().size()); - } - Unexpected("Peer type in AllowedReactionsCountValue."); + return rpl::combine( + FullReactionsCountValue(&peer->session()), + peer->session().changes().peerFlagsValue( + peer, + UpdateFlag::Reactions) + ) | rpl::map([=](int full, const auto&) { + const auto &allowed = Data::PeerAllowedReactions(peer); + return (allowed.type == Data::AllowedReactionsType::Some) + ? int(allowed.some.size()) + : full; }); } diff --git a/Telegram/SourceFiles/window/section_widget.cpp b/Telegram/SourceFiles/window/section_widget.cpp index 18473e465..1f3b5629d 100644 --- a/Telegram/SourceFiles/window/section_widget.cpp +++ b/Telegram/SourceFiles/window/section_widget.cpp @@ -351,10 +351,11 @@ bool ShowSendPremiumError( const auto type = peer->isBroadcast() ? ReactionDisableType::Channel : ReactionDisableType::Group; - if (const auto allowed = Data::PeerReactionsFilter(peer).allowed) { + const auto &allowed = Data::PeerAllowedReactions(peer); + if (!allowed.some.empty()) { for (const auto &reaction : list) { if (reaction.premium - && !allowed->contains(reaction.id.emoji())) { + && !ranges::contains(allowed.some, reaction.id)) { result.emplace(reaction.id, type); } }