From 22613fc204adcb81227220f8c0f3f3f8a2ee755c Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 18 May 2022 17:37:24 +0400 Subject: [PATCH] Show only one placeholder for premium reactions. --- .../boxes/peers/edit_peer_info_box.cpp | 2 +- .../data/data_message_reactions.cpp | 10 ++--- .../SourceFiles/data/data_message_reactions.h | 2 - .../SourceFiles/data/data_peer_values.cpp | 9 ++++ Telegram/SourceFiles/data/data_peer_values.h | 12 +++-- .../view/history_view_react_button.cpp | 45 ++++++++++++++++--- .../history/view/history_view_react_button.h | 5 +++ .../info/profile/info_profile_values.cpp | 3 +- .../window/window_filters_menu.cpp | 9 ++-- 9 files changed, 70 insertions(+), 27 deletions(-) diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 9d707d1c2..1e22b8a7c 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -1017,7 +1017,7 @@ void Controller::fillManageSection() { EditAllowedReactionsBox, !_peer->isBroadcast(), session->data().reactions().list( - Data::Reactions::Type::ActiveNonPremium), + Data::Reactions::Type::Active), *Data::PeerAllowedReactions(_peer), done)); }, diff --git a/Telegram/SourceFiles/data/data_message_reactions.cpp b/Telegram/SourceFiles/data/data_message_reactions.cpp index 8a1d3088f..651e48b10 100644 --- a/Telegram/SourceFiles/data/data_message_reactions.cpp +++ b/Telegram/SourceFiles/data/data_message_reactions.cpp @@ -19,6 +19,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_document.h" #include "data/data_document_media.h" #include "lottie/lottie_icon.h" +#include "storage/localimageloader.h" +#include "ui/image/image_location_factory.h" #include "base/timer_rpl.h" #include "apiwrap.h" #include "styles/style_chat.h" @@ -73,7 +75,6 @@ void Reactions::refresh() { const std::vector &Reactions::list(Type type) const { switch (type) { - case Type::ActiveNonPremium: return _activeNonPremium; case Type::Active: return _active; case Type::All: return _available; } @@ -302,7 +303,6 @@ void Reactions::updateFromData(const MTPDmessages_availableReactions &data) { _iconsCache.emplace(document, document->createMediaView()); } }; - _activeNonPremium.clear(); _active.clear(); _available.clear(); _active.reserve(list.size()); @@ -317,9 +317,6 @@ void Reactions::updateFromData(const MTPDmessages_availableReactions &data) { toCache(parsed->selectAnimation); toCache(parsed->centerIcon); toCache(parsed->aroundAnimation); - if (!parsed->premium) { - _activeNonPremium.push_back(*parsed); - } } } } @@ -339,6 +336,7 @@ std::optional Reactions::parse(const MTPAvailableReaction &entry) { } const auto selectAnimation = _owner->processDocument( data.vselect_animation()); + static auto test = 0; AssertIsDebug(); return known ? std::make_optional(Reaction{ .emoji = emoji, @@ -359,7 +357,7 @@ std::optional Reactions::parse(const MTPAvailableReaction &entry) { *data.varound_animation()).get() : nullptr), .active = !data.is_inactive(), - .premium = data.is_premium(), + .premium = (data.is_premium() || ((++test) % 2)), }) : std::nullopt; }); diff --git a/Telegram/SourceFiles/data/data_message_reactions.h b/Telegram/SourceFiles/data/data_message_reactions.h index 08d24e291..f1d553d82 100644 --- a/Telegram/SourceFiles/data/data_message_reactions.h +++ b/Telegram/SourceFiles/data/data_message_reactions.h @@ -40,7 +40,6 @@ public: void refresh(); enum class Type { - ActiveNonPremium, Active, All, }; @@ -103,7 +102,6 @@ private: const not_null _owner; - std::vector _activeNonPremium; std::vector _active; std::vector _available; QString _favorite; diff --git a/Telegram/SourceFiles/data/data_peer_values.cpp b/Telegram/SourceFiles/data/data_peer_values.cpp index 8b21f0e3f..efd30aadb 100644 --- a/Telegram/SourceFiles/data/data_peer_values.cpp +++ b/Telegram/SourceFiles/data/data_peer_values.cpp @@ -323,6 +323,15 @@ rpl::producer CanManageGroupCallValue(not_null peer) { return rpl::single(false); } +rpl::producer AmPremiumValue(not_null session) { + return session->user()->flagsValue( + ) | rpl::filter([=](UserData::Flags::Change change) { + return (change.diff & UserDataFlag::Premium); + }) | rpl::map([=] { + return session->user()->isPremium(); + }); +} + TimeId SortByOnlineValue(not_null user, TimeId now) { if (user->isServiceUser() || user->isBot()) { return -1; diff --git a/Telegram/SourceFiles/data/data_peer_values.h b/Telegram/SourceFiles/data/data_peer_values.h index 5e35e0aa8..c1f73eef5 100644 --- a/Telegram/SourceFiles/data/data_peer_values.h +++ b/Telegram/SourceFiles/data/data_peer_values.h @@ -104,12 +104,18 @@ inline auto PeerFullFlagValue( [[nodiscard]] rpl::producer CanWriteValue(ChatData *chat); [[nodiscard]] rpl::producer CanWriteValue(ChannelData *channel); [[nodiscard]] rpl::producer CanWriteValue(not_null peer); -[[nodiscard]] rpl::producer CanPinMessagesValue(not_null peer); -[[nodiscard]] rpl::producer CanManageGroupCallValue(not_null peer); +[[nodiscard]] rpl::producer CanPinMessagesValue( + not_null peer); +[[nodiscard]] rpl::producer CanManageGroupCallValue( + not_null peer); +[[nodiscard]] rpl::producer AmPremiumValue( + not_null session); [[nodiscard]] TimeId SortByOnlineValue(not_null user, TimeId now); [[nodiscard]] crl::time OnlineChangeTimeout(TimeId online, TimeId now); -[[nodiscard]] crl::time OnlineChangeTimeout(not_null user, TimeId now); +[[nodiscard]] crl::time OnlineChangeTimeout( + not_null user, + TimeId now); [[nodiscard]] QString OnlineText(TimeId online, TimeId now); [[nodiscard]] QString OnlineText(not_null user, TimeId now); [[nodiscard]] QString OnlineTextFull(not_null user, TimeId now); diff --git a/Telegram/SourceFiles/history/view/history_view_react_button.cpp b/Telegram/SourceFiles/history/view/history_view_react_button.cpp index 2aa24cf12..f841dbcc3 100644 --- a/Telegram/SourceFiles/history/view/history_view_react_button.cpp +++ b/Telegram/SourceFiles/history/view/history_view_react_button.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "data/data_document.h" #include "data/data_document_media.h" +#include "data/data_peer_values.h" #include "lang/lang_keys.h" #include "core/click_handler_types.h" #include "lottie/lottie_icon.h" @@ -467,6 +468,7 @@ void Manager::applyListFilters() { && (_buttonAlreadyNotMineCount >= limit); auto icons = std::vector>(); icons.reserve(_list.size()); + auto showPremiumLock = (ReactionIcons*)nullptr; auto favoriteIndex = -1; for (auto &icon : _list) { const auto &emoji = icon.emoji; @@ -474,14 +476,25 @@ void Manager::applyListFilters() { ? _buttonAlreadyList.contains(emoji) : (!_filter || _filter->contains(emoji)); if (add) { - if (emoji == _favorite) { - favoriteIndex = int(icons.size()); + if (icon.premium + && !_allowSendingPremium + && !_buttonAlreadyList.contains(emoji)) { + showPremiumLock = &icon; + } else { + icon.premiumLock = false; + if (emoji == _favorite) { + favoriteIndex = int(icons.size()); + } + icons.push_back(&icon); } - icons.push_back(&icon); } else { clearStateForHidden(icon); } } + if (showPremiumLock) { + showPremiumLock->premiumLock = true; + icons.push_back(showPremiumLock); + } if (favoriteIndex > 0) { const auto first = begin(icons); std::rotate(first, first + favoriteIndex, first + favoriteIndex + 1); @@ -492,7 +505,7 @@ void Manager::applyListFilters() { const auto selected = _selectedIcon; setSelectedIcon(-1); _icons = std::move(icons); - setSelectedIcon(selected < _icons.size() ? selected : -1); + setSelectedIcon((selected < _icons.size()) ? selected : -1); resolveMainReactionIcon(); } @@ -525,7 +538,7 @@ void Manager::updateButton(ButtonParameters parameters) { } _buttonContext = parameters.context; parameters.reactionsCount = _icons.size(); - if (!_buttonContext || _icons.empty()) { + if (!_buttonContext || !parameters.reactionsCount) { return; } else if (_button) { _button->applyParameters(parameters); @@ -564,7 +577,8 @@ void Manager::applyList( return std::tie( obj.emoji, obj.appearAnimation, - obj.selectAnimation); + obj.selectAnimation, + obj.premium); }; const auto favoriteChanged = (_favorite != favorite); if (favoriteChanged) { @@ -585,10 +599,11 @@ void Manager::applyList( .emoji = reaction.emoji, .appearAnimation = reaction.appearAnimation, .selectAnimation = reaction.selectAnimation, + .premium = reaction.premium, }); } applyListFilters(); - setSelectedIcon(selected < _icons.size() ? selected : -1); + setSelectedIcon((selected < _icons.size()) ? selected : -1); } void Manager::updateAllowedSublist(AllowedSublist filter) { @@ -599,6 +614,14 @@ void Manager::updateAllowedSublist(AllowedSublist filter) { applyListFilters(); } +void Manager::updateAllowSendingPremium(bool allow) { + if (_allowSendingPremium == allow) { + return; + } + _allowSendingPremium = allow; + applyListFilters(); +} + const Manager::AllowedSublist &Manager::allowedSublist() const { return _filter; } @@ -1348,6 +1371,8 @@ void Manager::paintAllEmoji( if (current) { clearStateForHidden(*icon); } + } else if (icon->premiumLock) { + p.fillRect(target, QColor(0, 128, 0, 128)); } else { const auto appear = icon->appear.get(); if (current @@ -1622,6 +1647,12 @@ void SetupManagerList( reactions->setFavorite(emoji); manager->updateButton({}); }, manager->lifetime()); + + Data::AmPremiumValue( + session + ) | rpl::start_with_next([=](bool premium) { + manager->updateAllowSendingPremium(premium); + }, manager->lifetime()); } IconFactory CachedIconFactory::createMethod() { diff --git a/Telegram/SourceFiles/history/view/history_view_react_button.h b/Telegram/SourceFiles/history/view/history_view_react_button.h index 10d3767a8..57bd072e4 100644 --- a/Telegram/SourceFiles/history/view/history_view_react_button.h +++ b/Telegram/SourceFiles/history/view/history_view_react_button.h @@ -149,6 +149,7 @@ public: const std::vector &list, const QString &favorite); void updateAllowedSublist(AllowedSublist filter); + void updateAllowSendingPremium(bool allow); [[nodiscard]] const AllowedSublist &allowedSublist() const; void updateUniqueLimit(not_null item); @@ -204,6 +205,8 @@ private: mutable ClickHandlerPtr link; mutable Ui::Animations::Simple selectedScale; bool appearAnimated = false; + bool premium = false; + bool premiumLock = false; mutable bool selected = false; mutable bool selectAnimated = false; }; @@ -340,8 +343,10 @@ private: rpl::variable _uniqueLimit = 0; base::flat_map, ReactionDocument> _loadCache; std::vector> _icons; + std::optional _premiumIcon; rpl::lifetime _loadCacheLifetime; bool _showingAll = false; + bool _allowSendingPremium = false; mutable int _selectedIcon = -1; std::optional _scheduledParameters; diff --git a/Telegram/SourceFiles/info/profile/info_profile_values.cpp b/Telegram/SourceFiles/info/profile/info_profile_values.cpp index 3367c9d70..f3315a7bd 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_values.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_values.cpp @@ -443,8 +443,7 @@ rpl::producer FullReactionsCountValue( return rpl::single(rpl::empty) | rpl::then( reactions->updates() ) | rpl::map([=] { - return int(reactions->list( - Data::Reactions::Type::ActiveNonPremium).size()); + return int(reactions->list(Data::Reactions::Type::Active).size()); }) | rpl::distinct_until_changed(); } diff --git a/Telegram/SourceFiles/window/window_filters_menu.cpp b/Telegram/SourceFiles/window/window_filters_menu.cpp index f20a18df9..74e953690 100644 --- a/Telegram/SourceFiles/window/window_filters_menu.cpp +++ b/Telegram/SourceFiles/window/window_filters_menu.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_chat_filters.h" #include "data/data_folder.h" #include "data/data_user.h" +#include "data/data_peer_values.h" #include "lang/lang_keys.h" #include "ui/filter_icons.h" #include "ui/wrap/vertical_layout_reorder.h" @@ -104,12 +105,8 @@ void FiltersMenu::setup() { _container->move(0, 0); }, _outer.lifetime()); - auto premium = _session->session().user()->flagsValue( - ) | rpl::filter([=](UserData::Flags::Change change) { - return (change.diff & UserDataFlag::Premium); - }) | rpl::map([=] { - return _session->session().user()->isPremium(); - }); + auto premium = Data::AmPremiumValue(&_session->session()); + const auto filters = &_session->session().data().chatsFilters(); rpl::combine( rpl::single(rpl::empty) | rpl::then(filters->changed()),