From 16942d487aec3dd0944ad9bdef79872dab999446 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 11 Jan 2024 12:29:23 +0400 Subject: [PATCH] New "Messages" privacy option and box. --- Telegram/Resources/langs/lang.strings | 12 ++ .../SourceFiles/boxes/edit_privacy_box.cpp | 155 ++++++++++++++++++ Telegram/SourceFiles/boxes/edit_privacy_box.h | 5 + Telegram/SourceFiles/settings/settings.style | 12 ++ .../settings/settings_privacy_security.cpp | 25 ++- Telegram/SourceFiles/ui/menu_icons.style | 1 + 6 files changed, 207 insertions(+), 3 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 73d0fde25..2e676016e 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -644,6 +644,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_phone_number_privacy" = "Phone number"; "lng_settings_forwards_privacy" = "Forwarded messages"; "lng_settings_profile_photo_privacy" = "Profile photo"; +"lng_settings_messages_privacy" = "Messages"; "lng_settings_voices_privacy" = "Voice messages"; "lng_settings_bio_privacy" = "Bio"; "lng_settings_privacy_premium" = "Only subscribers of {link} can restrict receiving voice messages."; @@ -1080,6 +1081,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_edit_privacy_contacts" = "My contacts"; "lng_edit_privacy_close_friends" = "Close friends"; "lng_edit_privacy_nobody" = "Nobody"; +"lng_edit_privacy_premium" = "Premium users"; "lng_edit_privacy_exceptions" = "Add exceptions"; "lng_edit_privacy_exceptions_count#one" = "{count} user"; @@ -1181,6 +1183,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_edit_privacy_voices_always_title" = "Always allow"; "lng_edit_privacy_voices_never_title" = "Never allow"; +"lng_messages_privacy_title" = "Messages"; +"lng_messages_privacy_subtitle" = "Who can send me messages?"; +"lng_messages_privacy_everyone" = "Everybody"; +"lng_messages_privacy_restricted" = "My Contacts and Premium Users"; +"lng_messages_privacy_about" = "You can restrict incoming messages to only contacts and Premium users."; +"lng_messages_privacy_premium_button" = "Subscribe to Telegram Premium"; +"lng_messages_privacy_premium_about" = "Subscribe now to change this setting and get access to other exclusive features of Telegram Premium."; +"lng_messages_privacy_premium" = "Only subscribers of {link} can select this option."; +"lng_messages_privacy_premium_link" = "Telegram Premium"; + "lng_self_destruct_title" = "Account self-destruction"; "lng_self_destruct_description" = "If you don't come online at least once within this period, your account will be deleted along with all groups, messages and contacts."; "lng_self_destruct_sessions_title" = "Session termination"; diff --git a/Telegram/SourceFiles/boxes/edit_privacy_box.cpp b/Telegram/SourceFiles/boxes/edit_privacy_box.cpp index 899c8be02..0a8bc866d 100644 --- a/Telegram/SourceFiles/boxes/edit_privacy_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_privacy_box.cpp @@ -7,15 +7,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/edit_privacy_box.h" +#include "api/api_global_privacy.h" +#include "ui/layers/generic_box.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/labels.h" #include "ui/widgets/buttons.h" +#include "ui/widgets/shadow.h" #include "ui/text/text_utilities.h" +#include "ui/toast/toast.h" #include "ui/wrap/slide_wrap.h" #include "ui/wrap/vertical_layout.h" +#include "ui/painter.h" #include "ui/vertical_list.h" #include "history/history.h" #include "boxes/peer_list_controllers.h" +#include "settings/settings_common.h" +#include "settings/settings_premium.h" #include "settings/settings_privacy_security.h" #include "calls/calls_instance.h" #include "base/binary_guard.h" @@ -28,8 +35,40 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_session_controller.h" #include "styles/style_settings.h" #include "styles/style_layers.h" +#include "styles/style_menu_icons.h" namespace { +namespace { + +void CreateRadiobuttonLock( + not_null widget, + const style::Checkbox &st) { + const auto lock = Ui::CreateChild(widget.get()); + lock->setAttribute(Qt::WA_TransparentForMouseEvents); + + lock->resize(st::defaultRadio.diameter, st::defaultRadio.diameter); + + widget->sizeValue( + ) | rpl::start_with_next([=, &st](QSize size) { + lock->move(st.checkPosition); + }, lock->lifetime()); + + lock->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(lock); + auto hq = PainterHighQualityEnabler(p); + const auto &icon = st::messagePrivacyLock; + const auto size = st::defaultRadio.diameter; + const auto image = icon.instance(st::checkboxFg->c); + const auto dimensions = image.size(); + p.drawImage(QRectF( + (size - icon.width()) / 2., + (size - icon.height()) / 2., + icon.width(), + icon.height()), image); + }, lock->lifetime()); +} + +} // namespace class PrivacyExceptionsBoxController : public ChatsListBoxController { public: @@ -394,3 +433,119 @@ void EditPrivacyBox::setupContent() { setDimensions(st::boxWideWidth, height); }, content->lifetime()); } + +void EditMessagesPrivacyBox( + not_null box, + not_null controller) { + box->setTitle(tr::lng_messages_privacy_title()); + box->setWidth(st::boxWideWidth); + + constexpr auto kOptionAll = 0; + constexpr auto kOptionPremium = 1; + + const auto premium = controller->session().premium(); + const auto privacy = &controller->session().api().globalPrivacy(); + const auto inner = box->verticalLayout(); + inner->add(object_ptr(box)); + + Ui::AddSkip(inner, st::messagePrivacyTopSkip); + Ui::AddSubsectionTitle(inner, tr::lng_messages_privacy_subtitle()); + const auto group = std::make_shared( + privacy->newRequirePremiumCurrent() ? kOptionPremium : kOptionAll); + inner->add( + object_ptr( + inner, + group, + kOptionAll, + tr::lng_messages_privacy_everyone(tr::now), + st::messagePrivacyCheck), + st::settingsSendTypePadding); + const auto restricted = inner->add( + object_ptr( + inner, + group, + kOptionPremium, + tr::lng_messages_privacy_restricted(tr::now), + st::messagePrivacyCheck), + st::settingsSendTypePadding + style::margins( + 0, + st::messagePrivacyRadioSkip, + 0, + st::messagePrivacyBottomSkip)); + + using WeakToast = base::weak_ptr; + const auto toast = std::make_shared(); + const auto showToast = [=] { + auto link = Ui::Text::Link( + Ui::Text::Semibold( + tr::lng_messages_privacy_premium_link(tr::now))); + (*toast) = controller->showToast({ + .text = tr::lng_messages_privacy_premium( + tr::now, + lt_link, + link, + Ui::Text::WithEntities), + .st = &st::defaultMultilineToast, + .duration = Ui::Toast::kDefaultDuration * 2, + .multiline = true, + .filter = crl::guard(&controller->session(), [=]( + const ClickHandlerPtr &, + Qt::MouseButton button) { + if (button == Qt::LeftButton) { + if (const auto strong = toast->get()) { + strong->hideAnimated(); + (*toast) = nullptr; + Settings::ShowPremium( + controller, + u"noncontact_peers_require_premium"_q); + return true; + } + } + return false; + }), + }); + }; + if (!premium) { + CreateRadiobuttonLock(restricted, st::messagePrivacyCheck); + + group->setChangedCallback([=](int value) { + if (value == kOptionPremium) { + group->setValue(kOptionAll); + showToast(); + } + }); + } + + Ui::AddDividerText(inner, tr::lng_messages_privacy_about()); + if (!premium) { + Ui::AddSkip(inner); + Settings::AddButtonWithIcon( + inner, + tr::lng_messages_privacy_premium_button(), + st::messagePrivacySubscribe, + { .icon = &st::menuBlueIconPremium } + )->setClickedCallback([=] { + Settings::ShowPremium( + controller, + u"noncontact_peers_require_premium"_q); + }); + Ui::AddSkip(inner); + Ui::AddDividerText(inner, tr::lng_messages_privacy_premium_about()); + box->addButton(tr::lng_about_done(), [=] { + box->closeBox(); + }); + } else { + box->addButton(tr::lng_settings_save(), [=] { + if (controller->session().premium()) { + privacy->updateNewRequirePremium( + group->value() == kOptionPremium); + box->closeBox(); + } else { + showToast(); + } + }); + box->addButton(tr::lng_cancel(), [=] { + box->closeBox(); + }); + } +} diff --git a/Telegram/SourceFiles/boxes/edit_privacy_box.h b/Telegram/SourceFiles/boxes/edit_privacy_box.h index d9ba7dab9..66cd75948 100644 --- a/Telegram/SourceFiles/boxes/edit_privacy_box.h +++ b/Telegram/SourceFiles/boxes/edit_privacy_box.h @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_user_privacy.h" namespace Ui { +class GenericBox; class VerticalLayout; class FlatLabel; class LinkButton; @@ -146,3 +147,7 @@ private: Value _value; }; + +void EditMessagesPrivacyBox( + not_null box, + not_null controller); diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index 616709700..c30940ca8 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -559,3 +559,15 @@ settingsColorButton: SettingsButton(settingsButton) { settingsColorRadioMargin: 17px; settingsColorRadioSkip: 13px; settingsColorRadioStroke: 2px; + +messagePrivacyTopSkip: 8px; +messagePrivacyRadioSkip: 6px; +messagePrivacyBottomSkip: 10px; +messagePrivacyCheck: Checkbox(settingsPrivacyOption) { + textPosition: point(13px, 1px); +} +messagePrivacySubscribe: SettingsButton(settingsButtonLight) { + padding: margins(56px, 10px, 22px, 8px); + iconLeft: 20px; +} +messagePrivacyLock: icon {{ "info/info_rights_lock", checkboxFg }}; diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/settings_privacy_security.cpp index 8da8dd901..bcd7f46b0 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_security.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_security.cpp @@ -195,9 +195,8 @@ void AddPremiumPrivacyButton( const auto showToast = [=] { auto link = Ui::Text::Link( - tr::lng_settings_privacy_premium_link(tr::now)); - link.entities.push_back( - EntityInText(EntityType::Semibold, 0, link.text.size())); + Ui::Text::Semibold( + tr::lng_settings_privacy_premium_link(tr::now))); (*toast) = controller->showToast({ .text = tr::lng_settings_privacy_premium( tr::now, @@ -242,6 +241,25 @@ void AddPremiumPrivacyButton( }); } +void AddMessagesPrivacyButton( + not_null controller, + not_null container) { + const auto session = &controller->session(); + const auto privacy = &session->api().globalPrivacy(); + AddButtonWithLabel( + container, + tr::lng_settings_messages_privacy(), + rpl::conditional( + privacy->newRequirePremium(), + tr::lng_edit_privacy_premium(), + tr::lng_edit_privacy_everyone()), + st::settingsButtonNoIcon, + {} + )->addClickHandler([=] { + controller->show(Box(EditMessagesPrivacyBox, controller)); + }); +} + rpl::producer BlockedPeersCount(not_null<::Main::Session*> session) { return session->api().blockedPeers().slice( ) | rpl::map([](const Api::BlockedPeers::Slice &data) { @@ -284,6 +302,7 @@ void SetupPrivacy( tr::lng_settings_profile_photo_privacy(), Key::ProfilePhoto, [] { return std::make_unique(); }); + AddMessagesPrivacyButton(controller, container); add( tr::lng_settings_bio_privacy(), Key::About, diff --git a/Telegram/SourceFiles/ui/menu_icons.style b/Telegram/SourceFiles/ui/menu_icons.style index 799110173..bf378fb1e 100644 --- a/Telegram/SourceFiles/ui/menu_icons.style +++ b/Telegram/SourceFiles/ui/menu_icons.style @@ -157,6 +157,7 @@ menuIconMuteForAnyTextPosition: point(14px, 9px); menuIconMuteForAnyTextFont: font(8px semibold); menuBlueIconPhotoSet: icon {{ "menu/photo_set", lightButtonFg }}; +menuBlueIconPremium: icon{{ "menu/premium", lightButtonFg }}; mediaMenuIconStickers: icon {{ "menu/stickers", mediaviewMenuFg }}; mediaMenuIconCancel: icon {{ "menu/cancel", mediaviewMenuFg }};