diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 6df4da1c10..7d6a1ff17d 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1195,6 +1195,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_quick_dialog_action_delete" = "Delete"; "lng_settings_quick_dialog_action_disabled" = "Change folder"; +"lng_settings_generic_subscribe" = "Subscribe to {link} to use this setting."; +"lng_settings_generic_subscribe_link" = "Telegram Premium"; + "lng_sessions_header" = "This device"; "lng_sessions_other_header" = "Active Devices"; "lng_sessions_other_desc" = "You can log in to Telegram from other mobile, tablet and desktop devices, using the same phone number. All your data will be instantly synchronized."; @@ -1310,6 +1313,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_edit_privacy_gifts_always_title" = "Always allow"; "lng_edit_privacy_gifts_never_title" = "Never allow"; +"lng_edit_privacy_gifts_types" = "Accepted Gift Types"; +"lng_edit_privacy_gifts_premium" = "Premium Subscriptions"; +"lng_edit_privacy_gifts_unlimited" = "Unlimited"; +"lng_edit_privacy_gifts_limited" = "Limited-Edition"; +"lng_edit_privacy_gifts_unique" = "Unique"; +"lng_edit_privacy_gifts_types_about" = "Choose the types of gifts that you accept."; +"lng_edit_privacy_gifts_show_icon" = "Show Gift Icon in Chats"; +"lng_edit_privacy_gifts_show_icon_about" = "Display the {emoji}Gift icon in the message input field for both participants in all chats."; + "lng_edit_privacy_calls_title" = "Calls"; "lng_edit_privacy_calls_header" = "Who can call me"; "lng_edit_privacy_calls_always_empty" = "Always allow"; diff --git a/Telegram/SourceFiles/api/api_global_privacy.cpp b/Telegram/SourceFiles/api/api_global_privacy.cpp index 01a6476c70..ffa85368d2 100644 --- a/Telegram/SourceFiles/api/api_global_privacy.cpp +++ b/Telegram/SourceFiles/api/api_global_privacy.cpp @@ -115,7 +115,9 @@ void GlobalPrivacy::updateHideReadTime(bool hide) { unarchiveOnNewMessageCurrent(), hide, newRequirePremiumCurrent(), - newChargeStarsCurrent()); + newChargeStarsCurrent(), + showGiftIconCurrent(), + disallowedGiftTypesCurrent()); } bool GlobalPrivacy::hideReadTimeCurrent() const { @@ -150,7 +152,39 @@ void GlobalPrivacy::updateMessagesPrivacy( unarchiveOnNewMessageCurrent(), hideReadTimeCurrent(), requirePremium, - chargeStars); + chargeStars, + showGiftIconCurrent(), + disallowedGiftTypesCurrent()); +} + +bool GlobalPrivacy::showGiftIconCurrent() const { + return _showGiftIcon.current(); +} + +rpl::producer GlobalPrivacy::showGiftIcon() const { + return _showGiftIcon.value(); +} + +DisallowedGiftTypes GlobalPrivacy::disallowedGiftTypesCurrent() const { + return _disallowedGiftTypes.current(); +} + +auto GlobalPrivacy::disallowedGiftTypes() const + -> rpl::producer { + return _disallowedGiftTypes.value(); +} + +void GlobalPrivacy::updateAdditionalGiftPrivacy( + DisallowedGiftTypes types, + bool showGiftIcon) { + update( + archiveAndMuteCurrent(), + unarchiveOnNewMessageCurrent(), + hideReadTimeCurrent(), + newRequirePremiumCurrent(), + newChargeStarsCurrent(), + showGiftIcon, + types); } void GlobalPrivacy::loadPaidReactionShownPeer() { @@ -182,7 +216,9 @@ void GlobalPrivacy::updateArchiveAndMute(bool value) { unarchiveOnNewMessageCurrent(), hideReadTimeCurrent(), newRequirePremiumCurrent(), - newChargeStarsCurrent()); + newChargeStarsCurrent(), + showGiftIconCurrent(), + disallowedGiftTypesCurrent()); } void GlobalPrivacy::updateUnarchiveOnNewMessage( @@ -192,7 +228,9 @@ void GlobalPrivacy::updateUnarchiveOnNewMessage( value, hideReadTimeCurrent(), newRequirePremiumCurrent(), - newChargeStarsCurrent()); + newChargeStarsCurrent(), + showGiftIconCurrent(), + disallowedGiftTypesCurrent()); } void GlobalPrivacy::update( @@ -200,8 +238,11 @@ void GlobalPrivacy::update( UnarchiveOnNewMessage unarchiveOnNewMessage, bool hideReadTime, bool newRequirePremium, - int newChargeStars) { + int newChargeStars, + bool showGiftIcon, + DisallowedGiftTypes disallowedGiftTypes) { using Flag = MTPDglobalPrivacySettings::Flag; + using DisallowedFlag = MTPDdisallowedStarGiftsSettings::Flag; _api.request(_requestId).cancel(); const auto newRequirePremiumAllowed = _session->premium() @@ -220,12 +261,27 @@ void GlobalPrivacy::update( | ((newRequirePremium && newRequirePremiumAllowed) ? Flag::f_new_noncontact_peers_require_premium : Flag()) - | Flag::f_noncontact_peers_paid_stars; + | Flag::f_noncontact_peers_paid_stars + | (showGiftIcon ? Flag::f_display_gifts_button : Flag()) + | Flag::f_disallowed_stargifts; + const auto disallowedFlags = DisallowedFlag() + | ((disallowedGiftTypes & DisallowedGiftType::Premium) + ? DisallowedFlag() AssertIsDebug() + : DisallowedFlag()) + | ((disallowedGiftTypes & DisallowedGiftType::Unlimited) + ? DisallowedFlag::f_disallow_unlimited_stargifts + : DisallowedFlag()) + | ((disallowedGiftTypes & DisallowedGiftType::Limited) + ? DisallowedFlag::f_disallow_limited_stargifts + : DisallowedFlag()) + | ((disallowedGiftTypes & DisallowedGiftType::Unique) + ? DisallowedFlag::f_disallow_unique_stargifts + : DisallowedFlag()); _requestId = _api.request(MTPaccount_SetGlobalPrivacySettings( MTP_globalPrivacySettings( MTP_flags(flags), MTP_long(newChargeStars), - MTPDisallowedStarGiftsSettings()) + MTP_disallowedStarGiftsSettings(MTP_flags(disallowedFlags))) )).done([=](const MTPGlobalPrivacySettings &result) { _requestId = 0; apply(result); @@ -237,7 +293,9 @@ void GlobalPrivacy::update( unarchiveOnNewMessage, hideReadTime, false, - 0); + 0, + false, + DisallowedGiftTypes()); } }).send(); _archiveAndMute = archiveAndMute; @@ -245,6 +303,8 @@ void GlobalPrivacy::update( _hideReadTime = hideReadTime; _newRequirePremium = newRequirePremium; _newChargeStars = newChargeStars; + _disallowedGiftTypes = disallowedGiftTypes; + _showGiftIcon = showGiftIcon; } void GlobalPrivacy::apply(const MTPGlobalPrivacySettings &settings) { @@ -258,6 +318,22 @@ void GlobalPrivacy::apply(const MTPGlobalPrivacySettings &settings) { _hideReadTime = data.is_hide_read_marks(); _newRequirePremium = data.is_new_noncontact_peers_require_premium(); _newChargeStars = data.vnoncontact_peers_paid_stars().value_or_empty(); + _showGiftIcon = data.is_display_gifts_button(); + if (const auto gifts = data.vdisallowed_stargifts()) { + const auto &data = gifts->data(); + _disallowedGiftTypes = DisallowedGiftType() + | (data.is_disallow_unlimited_stargifts() + ? DisallowedGiftType::Unlimited + : DisallowedGiftType()) + | (data.is_disallow_limited_stargifts() + ? DisallowedGiftType::Limited + : DisallowedGiftType()) + | (data.is_disallow_unique_stargifts() + ? DisallowedGiftType::Unique + : DisallowedGiftType()); + } else { + _disallowedGiftTypes = DisallowedGiftTypes(); + } } } // namespace Api diff --git a/Telegram/SourceFiles/api/api_global_privacy.h b/Telegram/SourceFiles/api/api_global_privacy.h index 6b0fc064b3..59b6d7860e 100644 --- a/Telegram/SourceFiles/api/api_global_privacy.h +++ b/Telegram/SourceFiles/api/api_global_privacy.h @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +#include "base/flags.h" #include "mtproto/sender.h" class ApiWrap; @@ -23,6 +24,16 @@ enum class UnarchiveOnNewMessage { AnyUnmuted, }; +enum class DisallowedGiftType { + Premium = 0x01, + Unlimited = 0x02, + Limited = 0x04, + Unique = 0x08, +}; +inline constexpr bool is_flag_type(DisallowedGiftType) { return true; } + +using DisallowedGiftTypes = base::flags; + [[nodiscard]] PeerId ParsePaidReactionShownPeer( not_null session, const MTPPaidReactionPrivacy &value); @@ -57,6 +68,15 @@ public: void updateMessagesPrivacy(bool requirePremium, int chargeStars); + [[nodiscard]] bool showGiftIconCurrent() const; + [[nodiscard]] rpl::producer showGiftIcon() const; + [[nodiscard]] DisallowedGiftTypes disallowedGiftTypesCurrent() const; + [[nodiscard]] auto disallowedGiftTypes() const + -> rpl::producer; + void updateAdditionalGiftPrivacy( + DisallowedGiftTypes types, + bool showGiftIcon); + void loadPaidReactionShownPeer(); void updatePaidReactionShownPeer(PeerId shownPeer); [[nodiscard]] PeerId paidReactionShownPeerCurrent() const; @@ -70,7 +90,9 @@ private: UnarchiveOnNewMessage unarchiveOnNewMessage, bool hideReadTime, bool newRequirePremium, - int newChargeStars); + int newChargeStars, + bool showGiftIcon, + DisallowedGiftTypes disallowedGiftTypes); const not_null _session; MTP::Sender _api; @@ -82,6 +104,8 @@ private: rpl::variable _hideReadTime = false; rpl::variable _newRequirePremium = false; rpl::variable _newChargeStars = 0; + rpl::variable _showGiftIcon = false; + rpl::variable _disallowedGiftTypes; rpl::variable _paidReactionShownPeer = false; std::vector> _callbacks; bool _paidReactionShownPeerLoaded = false; diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index b866ec905a..22dee0c6f0 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -684,3 +684,8 @@ settingsChatLinkField: InputField(defaultInputField) { } settingsQuickDialogActionsTriggerFont: font(11px); + +settingsGiftIconEmoji: IconEmoji { + icon: icon{{ "menu/gift_premium", windowFg }}; + padding: margins(0px, 1px, 0px, 0px); +} diff --git a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp index a843d7f046..e7e3363931 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp @@ -616,8 +616,8 @@ object_ptr PhoneNumberPrivacyController::setupMiddleWidget( } void PhoneNumberPrivacyController::saveAdditional() { - if (_saveAdditional) { - _saveAdditional(); + if (const auto onstack = _saveAdditional) { + onstack(); } } @@ -1296,8 +1296,8 @@ object_ptr ProfilePhotoPrivacyController::setupMiddleWidget( } void ProfilePhotoPrivacyController::saveAdditional() { - if (_saveAdditional) { - _saveAdditional(); + if (const auto onstack = _saveAdditional) { + onstack(); } } @@ -1626,4 +1626,132 @@ bool GiftsAutoSavePrivacyController::allowMiniAppsToggle( return true; } +object_ptr GiftsAutoSavePrivacyController::setupBelowWidget( + not_null controller, + not_null parent, + rpl::producer