/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "settings/settings_privacy_security.h" #include "api/api_authorizations.h" #include "api/api_cloud_password.h" #include "api/api_self_destruct.h" #include "api/api_sensitive_content.h" #include "api/api_global_privacy.h" #include "api/api_websites.h" #include "settings/cloud_password/settings_cloud_password_email_confirm.h" #include "settings/cloud_password/settings_cloud_password_input.h" #include "settings/cloud_password/settings_cloud_password_start.h" #include "settings/settings_blocked_peers.h" #include "settings/settings_global_ttl.h" #include "settings/settings_local_passcode.h" #include "settings/settings_premium.h" // Settings::ShowPremium. #include "settings/settings_privacy_controllers.h" #include "settings/settings_websites.h" #include "base/timer_rpl.h" #include "boxes/passcode_box.h" #include "boxes/sessions_box.h" #include "ui/boxes/confirm_box.h" #include "boxes/self_destruction_box.h" #include "core/application.h" #include "core/core_settings.h" #include "ui/chat/chat_style.h" #include "ui/effects/premium_top_bar.h" #include "ui/text/format_values.h" #include "ui/text/text_utilities.h" #include "ui/toast/toast.h" #include "ui/wrap/slide_wrap.h" #include "ui/wrap/fade_wrap.h" #include "ui/widgets/shadow.h" #include "ui/widgets/checkbox.h" #include "ui/vertical_list.h" #include "ui/rect.h" #include "calls/calls_instance.h" #include "core/update_checker.h" #include "lang/lang_keys.h" #include "data/data_session.h" #include "data/data_chat.h" #include "data/data_channel.h" #include "data/data_peer_values.h" #include "main/main_domain.h" #include "main/main_session.h" #include "storage/storage_domain.h" #include "window/window_session_controller.h" #include "apiwrap.h" #include "styles/style_settings.h" #include "styles/style_menu_icons.h" #include "styles/style_layers.h" #include #include namespace Settings { namespace { constexpr auto kUpdateTimeout = 60 * crl::time(1000); using Privacy = Api::UserPrivacy; [[nodiscard]] QImage PremiumStar() { const auto factor = style::DevicePixelRatio(); const auto size = Size(st::settingsButtonNoIcon.style.font->ascent); auto image = QImage( size * factor, QImage::Format_ARGB32_Premultiplied); image.setDevicePixelRatio(factor); image.fill(Qt::transparent); { auto p = QPainter(&image); auto star = QSvgRenderer(Ui::Premium::ColorizedSvg()); star.render(&p, Rect(size)); } return image; } void AddPremiumStar( not_null button, not_null session, rpl::producer label, const QMargins &padding) { const auto badge = Ui::CreateChild(button.get()); badge->showOn(Data::AmPremiumValue(session)); const auto sampleLeft = st::settingsColorSamplePadding.left(); const auto badgeLeft = padding.left() + sampleLeft; auto star = PremiumStar(); badge->resize(star.size() / style::DevicePixelRatio()); badge->paintRequest( ) | rpl::start_with_next([=] { auto p = QPainter(badge); p.drawImage(0, 0, star); }, badge->lifetime()); rpl::combine( button->sizeValue(), std::move(label) ) | rpl::start_with_next([=](const QSize &s, const QString &) { if (s.isNull()) { return; } badge->moveToLeft( button->fullTextWidth() + badgeLeft, (s.height() - badge->height()) / 2); }, badge->lifetime()); } QString PrivacyBase(Privacy::Key key, Privacy::Option option) { using Key = Privacy::Key; using Option = Privacy::Option; switch (key) { case Key::CallsPeer2Peer: switch (option) { case Option::Everyone: return tr::lng_edit_privacy_calls_p2p_everyone(tr::now); case Option::Contacts: return tr::lng_edit_privacy_calls_p2p_contacts(tr::now); case Option::CloseFriends: return tr::lng_edit_privacy_close_friends(tr::now); // unused case Option::Nobody: return tr::lng_edit_privacy_calls_p2p_nobody(tr::now); } Unexpected("Value in Privacy::Option."); default: switch (option) { case Option::Everyone: return tr::lng_edit_privacy_everyone(tr::now); case Option::Contacts: return tr::lng_edit_privacy_contacts(tr::now); case Option::CloseFriends: return tr::lng_edit_privacy_close_friends(tr::now); case Option::Nobody: return tr::lng_edit_privacy_nobody(tr::now); } Unexpected("Value in Privacy::Option."); } } rpl::producer PrivacyString( not_null<::Main::Session*> session, Privacy::Key key) { session->api().userPrivacy().reload(key); return session->api().userPrivacy().value( key ) | rpl::map([=](const Privacy::Rule &value) { auto add = QStringList(); if (const auto never = ExceptionUsersCount(value.never)) { add.push_back("-" + QString::number(never)); } if (const auto always = ExceptionUsersCount(value.always)) { add.push_back("+" + QString::number(always)); } if (!add.isEmpty()) { return PrivacyBase(key, value.option) + " (" + add.join(", ") + ")"; } else { return PrivacyBase(key, value.option); } }); } #if 0 // Dead code. void AddPremiumPrivacyButton( not_null controller, not_null container, rpl::producer label, Privacy::Key key, Fn()> controllerFactory) { const auto shower = Ui::CreateChild(container.get()); const auto session = &controller->session(); const auto &st = st::settingsButtonNoIcon; const auto button = container->add(object_ptr