| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872 |
- /*
- 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_main.h"
- #include "api/api_credits.h"
- #include "core/application.h"
- #include "core/click_handler_types.h"
- #include "settings/settings_advanced.h"
- #include "settings/settings_business.h"
- #include "settings/settings_calls.h"
- #include "settings/settings_chat.h"
- #include "settings/settings_codes.h"
- #include "settings/settings_credits.h"
- #include "settings/settings_folders.h"
- #include "settings/settings_information.h"
- #include "settings/settings_notifications.h"
- #include "settings/settings_power_saving.h"
- #include "settings/settings_premium.h"
- #include "settings/settings_privacy_security.h"
- #include "settings/settings_scale_preview.h"
- #include "boxes/language_box.h"
- #include "boxes/username_box.h"
- #include "boxes/about_box.h"
- #include "boxes/star_gift_box.h"
- #include "ui/basic_click_handlers.h"
- #include "ui/boxes/confirm_box.h"
- #include "ui/controls/userpic_button.h"
- #include "ui/effects/premium_graphics.h"
- #include "ui/effects/premium_top_bar.h" // Ui::Premium::ColorizedSvg.
- #include "ui/wrap/slide_wrap.h"
- #include "ui/widgets/menu/menu_add_action_callback.h"
- #include "ui/widgets/continuous_sliders.h"
- #include "ui/widgets/popup_menu.h"
- #include "ui/text/text_utilities.h"
- #include "ui/toast/toast.h"
- #include "ui/new_badges.h"
- #include "ui/rect.h"
- #include "ui/vertical_list.h"
- #include "info/profile/info_profile_badge.h"
- #include "info/profile/info_profile_emoji_status_panel.h"
- #include "data/components/credits.h"
- #include "data/data_user.h"
- #include "data/data_session.h"
- #include "data/data_cloud_themes.h"
- #include "data/data_chat_filters.h"
- #include "lang/lang_cloud_manager.h"
- #include "lang/lang_instance.h"
- #include "storage/localstorage.h"
- #include "main/main_session.h"
- #include "main/main_session_settings.h"
- #include "main/main_account.h"
- #include "main/main_domain.h"
- #include "main/main_app_config.h"
- #include "apiwrap.h"
- #include "api/api_peer_photo.h"
- #include "api/api_cloud_password.h"
- #include "api/api_global_privacy.h"
- #include "api/api_sensitive_content.h"
- #include "api/api_premium.h"
- #include "info/profile/info_profile_values.h"
- #include "window/window_controller.h"
- #include "window/window_session_controller.h"
- #include "base/call_delayed.h"
- #include "base/platform/base_platform_info.h"
- #include "styles/style_settings.h"
- #include "styles/style_info.h"
- #include "styles/style_menu_icons.h"
- #include <QtGui/QGuiApplication>
- #include <QtGui/QClipboard>
- #include <QtGui/QWindow>
- namespace Settings {
- namespace {
- class Cover final : public Ui::FixedHeightWidget {
- public:
- Cover(
- QWidget *parent,
- not_null<Window::SessionController*> controller,
- not_null<UserData*> user);
- ~Cover();
- private:
- void setupChildGeometry();
- void initViewers();
- void refreshStatusText();
- void refreshNameGeometry(int newWidth);
- void refreshPhoneGeometry(int newWidth);
- void refreshUsernameGeometry(int newWidth);
- const not_null<Window::SessionController*> _controller;
- const not_null<UserData*> _user;
- Info::Profile::EmojiStatusPanel _emojiStatusPanel;
- Info::Profile::Badge _badge;
- object_ptr<Ui::UserpicButton> _userpic;
- object_ptr<Ui::FlatLabel> _name = { nullptr };
- object_ptr<Ui::FlatLabel> _phone = { nullptr };
- object_ptr<Ui::FlatLabel> _username = { nullptr };
- };
- Cover::Cover(
- QWidget *parent,
- not_null<Window::SessionController*> controller,
- not_null<UserData*> user)
- : FixedHeightWidget(
- parent,
- st::settingsPhotoTop
- + st::infoProfileCover.photo.size.height()
- + st::settingsPhotoBottom)
- , _controller(controller)
- , _user(user)
- , _badge(
- this,
- st::infoPeerBadge,
- &user->session(),
- Info::Profile::BadgeContentForPeer(user),
- &_emojiStatusPanel,
- [=] {
- return controller->isGifPausedAtLeastFor(
- Window::GifPauseReason::Layer);
- },
- 0, // customStatusLoopsLimit
- Info::Profile::BadgeType::Premium)
- , _userpic(
- this,
- controller,
- _user,
- Ui::UserpicButton::Role::OpenPhoto,
- Ui::UserpicButton::Source::PeerPhoto,
- st::infoProfileCover.photo)
- , _name(this, st::infoProfileCover.name)
- , _phone(this, st::defaultFlatLabel)
- , _username(this, st::infoProfileMegagroupCover.status) {
- _user->updateFull();
- _name->setSelectable(true);
- _name->setContextCopyText(tr::lng_profile_copy_fullname(tr::now));
- _phone->setSelectable(true);
- _phone->setContextCopyText(tr::lng_profile_copy_phone(tr::now));
- const auto hook = [=](Ui::FlatLabel::ContextMenuRequest request) {
- if (request.selection.empty()) {
- const auto c = [=] {
- auto phone = rpl::variable<TextWithEntities>(
- Info::Profile::PhoneValue(_user)).current().text;
- phone.replace(' ', QString()).replace('-', QString());
- TextUtilities::SetClipboardText({ phone });
- };
- request.menu->addAction(tr::lng_profile_copy_phone(tr::now), c);
- } else {
- _phone->fillContextMenu(request);
- }
- };
- _phone->setContextMenuHook(hook);
- initViewers();
- setupChildGeometry();
- _userpic->switchChangePhotoOverlay(_user->isSelf(), [=](
- Ui::UserpicButton::ChosenImage chosen) {
- auto &image = chosen.image;
- _userpic->showCustom(base::duplicate(image));
- _user->session().api().peerPhoto().upload(
- _user,
- {
- std::move(image),
- chosen.markup.documentId,
- chosen.markup.colors,
- });
- });
- _badge.setPremiumClickCallback([=] {
- _emojiStatusPanel.show(
- _controller,
- _badge.widget(),
- _badge.sizeTag());
- });
- _badge.updated() | rpl::start_with_next([=] {
- refreshNameGeometry(width());
- }, _name->lifetime());
- }
- Cover::~Cover() = default;
- void Cover::setupChildGeometry() {
- using namespace rpl::mappers;
- widthValue(
- ) | rpl::start_with_next([=](int newWidth) {
- _userpic->moveToLeft(
- st::settingsPhotoLeft,
- st::settingsPhotoTop,
- newWidth);
- refreshNameGeometry(newWidth);
- refreshPhoneGeometry(newWidth);
- refreshUsernameGeometry(newWidth);
- }, lifetime());
- }
- void Cover::initViewers() {
- Info::Profile::NameValue(
- _user
- ) | rpl::start_with_next([=](const QString &name) {
- _name->setText(name);
- refreshNameGeometry(width());
- }, lifetime());
- Info::Profile::PhoneValue(
- _user
- ) | rpl::start_with_next([=](const TextWithEntities &value) {
- _phone->setText(value.text);
- refreshPhoneGeometry(width());
- }, lifetime());
- Info::Profile::UsernameValue(
- _user
- ) | rpl::start_with_next([=](const TextWithEntities &value) {
- _username->setMarkedText(Ui::Text::Link(value.text.isEmpty()
- ? tr::lng_settings_username_add(tr::now)
- : value.text));
- refreshUsernameGeometry(width());
- }, lifetime());
- _username->overrideLinkClickHandler([=] {
- const auto username = _user->username();
- if (username.isEmpty()) {
- _controller->show(Box(UsernamesBox, _user));
- } else {
- QGuiApplication::clipboard()->setText(
- _user->session().createInternalLinkFull(username));
- _controller->showToast(tr::lng_username_copied(tr::now));
- }
- });
- }
- void Cover::refreshNameGeometry(int newWidth) {
- const auto nameLeft = st::settingsNameLeft;
- const auto nameTop = st::settingsNameTop;
- auto nameWidth = newWidth
- - nameLeft
- - st::infoProfileCover.rightSkip;
- if (const auto width = _badge.widget() ? _badge.widget()->width() : 0) {
- nameWidth -= st::infoVerifiedCheckPosition.x() + width;
- }
- _name->resizeToNaturalWidth(nameWidth);
- _name->moveToLeft(nameLeft, nameTop, newWidth);
- const auto badgeLeft = nameLeft + _name->width();
- const auto badgeTop = nameTop;
- const auto badgeBottom = nameTop + _name->height();
- _badge.move(badgeLeft, badgeTop, badgeBottom);
- }
- void Cover::refreshPhoneGeometry(int newWidth) {
- const auto phoneLeft = st::settingsPhoneLeft;
- const auto phoneTop = st::settingsPhoneTop;
- const auto phoneWidth = newWidth
- - phoneLeft
- - st::infoProfileCover.rightSkip;
- _phone->resizeToWidth(phoneWidth);
- _phone->moveToLeft(phoneLeft, phoneTop, newWidth);
- }
- void Cover::refreshUsernameGeometry(int newWidth) {
- const auto usernameLeft = st::settingsUsernameLeft;
- const auto usernameTop = st::settingsUsernameTop;
- const auto usernameRight = st::infoProfileCover.rightSkip;
- const auto usernameWidth = newWidth - usernameLeft - usernameRight;
- _username->resizeToWidth(usernameWidth);
- _username->moveToLeft(usernameLeft, usernameTop, newWidth);
- }
- [[nodiscard]] not_null<Ui::SettingsButton*> AddPremiumStar(
- not_null<Ui::SettingsButton*> button,
- bool credits,
- Fn<bool()> isPaused) {
- const auto stops = credits
- ? Ui::Premium::CreditsIconGradientStops()
- : Ui::Premium::ButtonGradientStops();
- const auto ministarsContainer = Ui::CreateChild<Ui::RpWidget>(button);
- const auto &buttonSt = button->st();
- const auto fullHeight = buttonSt.height
- + rect::m::sum::v(buttonSt.padding);
- using MiniStars = Ui::Premium::ColoredMiniStars;
- const auto ministars = button->lifetime().make_state<MiniStars>(
- ministarsContainer,
- false);
- ministars->setColorOverride(stops);
- const auto isPausedValue
- = button->lifetime().make_state<rpl::variable<bool>>(isPaused());
- isPausedValue->value() | rpl::start_with_next([=](bool value) {
- ministars->setPaused(value);
- }, ministarsContainer->lifetime());
- ministarsContainer->paintRequest(
- ) | rpl::start_with_next([=] {
- (*isPausedValue) = isPaused();
- auto p = QPainter(ministarsContainer);
- {
- constexpr auto kScale = 0.35;
- const auto r = ministarsContainer->rect();
- p.translate(r.center());
- p.scale(kScale, kScale);
- p.translate(-r.center());
- }
- ministars->paint(p);
- }, ministarsContainer->lifetime());
- const auto badge = Ui::CreateChild<Ui::RpWidget>(button.get());
- auto star = [&] {
- 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(stops));
- star.render(&p, Rect(size));
- }
- return image;
- }();
- badge->resize(star.size() / style::DevicePixelRatio());
- badge->paintRequest(
- ) | rpl::start_with_next([=] {
- auto p = QPainter(badge);
- p.drawImage(0, 0, star);
- }, badge->lifetime());
- button->sizeValue(
- ) | rpl::start_with_next([=](const QSize &s) {
- badge->moveToLeft(
- button->st().iconLeft
- + (st::menuIconShop.width() - badge->width()) / 2,
- (s.height() - badge->height()) / 2);
- ministarsContainer->moveToLeft(
- badge->x() - (fullHeight - badge->height()) / 2,
- 0);
- }, badge->lifetime());
- ministarsContainer->resize(fullHeight, fullHeight);
- ministars->setCenter(ministarsContainer->rect());
- return button;
- }
- } // namespace
- void SetupPowerSavingButton(
- not_null<Window::Controller*> window,
- not_null<Ui::VerticalLayout*> container) {
- const auto button = AddButtonWithIcon(
- container,
- tr::lng_settings_power_menu(),
- st::settingsButton,
- { &st::menuIconPowerUsage });
- button->setClickedCallback([=] {
- window->show(Box(PowerSavingBox));
- });
- }
- void SetupLanguageButton(
- not_null<Window::Controller*> window,
- not_null<Ui::VerticalLayout*> container) {
- const auto button = AddButtonWithLabel(
- container,
- tr::lng_settings_language(),
- rpl::single(
- Lang::GetInstance().id()
- ) | rpl::then(
- Lang::GetInstance().idChanges()
- ) | rpl::map([] { return Lang::GetInstance().nativeName(); }),
- st::settingsButton,
- { &st::menuIconTranslate });
- const auto guard = Ui::CreateChild<base::binary_guard>(button.get());
- button->addClickHandler([=] {
- const auto m = button->clickModifiers();
- if ((m & Qt::ShiftModifier) && (m & Qt::AltModifier)) {
- Lang::CurrentCloudManager().switchToLanguage({ u"#custom"_q });
- } else {
- *guard = LanguageBox::Show(window->sessionController());
- }
- });
- }
- void SetupSections(
- not_null<Window::SessionController*> controller,
- not_null<Ui::VerticalLayout*> container,
- Fn<void(Type)> showOther) {
- Ui::AddDivider(container);
- Ui::AddSkip(container);
- const auto addSection = [&](
- rpl::producer<QString> label,
- Type type,
- IconDescriptor &&descriptor) {
- AddButtonWithIcon(
- container,
- std::move(label),
- st::settingsButton,
- std::move(descriptor)
- )->addClickHandler([=] {
- showOther(type);
- });
- };
- if (controller->session().supportMode()) {
- SetupSupport(controller, container);
- Ui::AddDivider(container);
- Ui::AddSkip(container);
- } else {
- addSection(
- tr::lng_settings_my_account(),
- Information::Id(),
- { &st::menuIconProfile });
- }
- addSection(
- tr::lng_settings_section_notify(),
- Notifications::Id(),
- { &st::menuIconNotifications });
- addSection(
- tr::lng_settings_section_privacy(),
- PrivacySecurity::Id(),
- { &st::menuIconLock });
- addSection(
- tr::lng_settings_section_chat_settings(),
- Chat::Id(),
- { &st::menuIconChatBubble });
- const auto preload = [=] {
- controller->session().data().chatsFilters().requestSuggested();
- };
- const auto account = &controller->session().account();
- const auto slided = container->add(
- object_ptr<Ui::SlideWrap<Ui::SettingsButton>>(
- container,
- CreateButtonWithIcon(
- container,
- tr::lng_settings_section_filters(),
- st::settingsButton,
- { &st::menuIconShowInFolder }))
- )->setDuration(0);
- if (controller->session().data().chatsFilters().has()
- || controller->session().settings().dialogsFiltersEnabled()) {
- slided->show(anim::type::instant);
- preload();
- } else {
- const auto enabled = [=] {
- const auto result = account->appConfig().get<bool>(
- u"dialog_filters_enabled"_q,
- false);
- if (result) {
- preload();
- }
- return result;
- };
- const auto preloadIfEnabled = [=](bool enabled) {
- if (enabled) {
- preload();
- }
- };
- slided->toggleOn(
- rpl::single(rpl::empty) | rpl::then(
- account->appConfig().refreshed()
- ) | rpl::map(
- enabled
- ) | rpl::before_next(preloadIfEnabled));
- }
- slided->entity()->setClickedCallback([=] {
- showOther(Folders::Id());
- });
- addSection(
- tr::lng_settings_advanced(),
- Advanced::Id(),
- { &st::menuIconManage });
- addSection(
- tr::lng_settings_section_devices(),
- Calls::Id(),
- { &st::menuIconUnmute });
- SetupPowerSavingButton(&controller->window(), container);
- SetupLanguageButton(&controller->window(), container);
- Ui::AddSkip(container);
- }
- void SetupPremium(
- not_null<Window::SessionController*> controller,
- not_null<Ui::VerticalLayout*> container,
- Fn<void(Type)> showOther) {
- if (!controller->session().premiumPossible()) {
- return;
- }
- Ui::AddDivider(container);
- Ui::AddSkip(container);
- const auto isPaused = Window::PausedIn(
- controller,
- Window::GifPauseReason::Any);
- AddPremiumStar(
- AddButtonWithIcon(
- container,
- tr::lng_premium_summary_title(),
- st::settingsButton),
- false,
- isPaused
- )->addClickHandler([=] {
- controller->setPremiumRef("settings");
- showOther(PremiumId());
- });
- {
- controller->session().credits().load();
- AddPremiumStar(
- AddButtonWithLabel(
- container,
- tr::lng_settings_credits(),
- controller->session().credits().balanceValue(
- ) | rpl::map([=](StarsAmount c) {
- return c
- ? Lang::FormatStarsAmountToShort(c).string
- : QString();
- }),
- st::settingsButton),
- true,
- isPaused
- )->addClickHandler([=] {
- controller->setPremiumRef("settings");
- showOther(CreditsId());
- });
- }
- const auto button = AddButtonWithIcon(
- container,
- tr::lng_business_title(),
- st::settingsButton,
- { .icon = &st::menuIconShop });
- button->addClickHandler([=] {
- showOther(BusinessId());
- });
- Ui::NewBadge::AddToRight(button);
- if (controller->session().premiumCanBuy()) {
- const auto button = AddButtonWithIcon(
- container,
- tr::lng_settings_gift_premium(),
- st::settingsButton,
- { .icon = &st::menuIconGiftPremium }
- );
- button->addClickHandler([=] {
- Ui::ChooseStarGiftRecipient(controller);
- });
- }
- Ui::AddSkip(container);
- }
- bool HasInterfaceScale() {
- return true;
- }
- void SetupInterfaceScale(
- not_null<Window::Controller*> window,
- not_null<Ui::VerticalLayout*> container,
- bool icon) {
- if (!HasInterfaceScale()) {
- return;
- }
- const auto toggled = Ui::CreateChild<rpl::event_stream<bool>>(
- container.get());
- const auto switched = (cConfigScale() == style::kScaleAuto);
- const auto button = AddButtonWithIcon(
- container,
- tr::lng_settings_default_scale(),
- icon ? st::settingsButton : st::settingsButtonNoIcon,
- { icon ? &st::menuIconShowInChat : nullptr }
- )->toggleOn(toggled->events_starting_with_copy(switched));
- const auto ratio = style::DevicePixelRatio();
- const auto scaleMin = style::kScaleMin;
- const auto scaleMax = style::MaxScaleForRatio(ratio);
- const auto scaleConfig = cConfigScale();
- const auto step = 5;
- Assert(!((scaleMax - scaleMin) % step));
- auto values = std::vector<int>();
- for (auto i = scaleMin; i != scaleMax; i += step) {
- values.push_back(i);
- if (scaleConfig > i && scaleConfig < i + step) {
- values.push_back(scaleConfig);
- }
- }
- values.push_back(scaleMax);
- const auto valuesCount = int(values.size());
- const auto valueFromScale = [=](int scale) {
- scale = cEvalScale(scale);
- auto result = 0;
- for (const auto value : values) {
- if (scale == value) {
- break;
- }
- ++result;
- }
- return ((result == valuesCount) ? (result - 1) : result)
- / float64(valuesCount - 1);
- };
- auto sliderWithLabel = MakeSliderWithLabel(
- container,
- st::settingsScale,
- st::settingsScaleLabel,
- st::normalFont->spacew * 2,
- st::settingsScaleLabel.style.font->width("300%"),
- true);
- container->add(
- std::move(sliderWithLabel.widget),
- icon ? st::settingsScalePadding : st::settingsBigScalePadding);
- const auto slider = sliderWithLabel.slider;
- const auto label = sliderWithLabel.label;
- const auto updateLabel = [=](int scale) {
- const auto labelText = [&](int scale) {
- if constexpr (Platform::IsMac()) {
- return QString::number(scale) + '%';
- } else {
- const auto handle = window->widget()->windowHandle();
- const auto ratio = handle->devicePixelRatio();
- return QString::number(base::SafeRound(scale * ratio)) + '%';
- }
- };
- label->setText(labelText(cEvalScale(scale)));
- };
- updateLabel(cConfigScale());
- const auto inSetScale = container->lifetime().make_state<bool>();
- const auto setScale = [=](int scale, const auto &repeatSetScale) -> void {
- if (*inSetScale) {
- return;
- }
- *inSetScale = true;
- const auto guard = gsl::finally([=] { *inSetScale = false; });
- updateLabel(scale);
- toggled->fire(scale == style::kScaleAuto);
- slider->setValue(valueFromScale(scale));
- if (cEvalScale(scale) != cEvalScale(cConfigScale())) {
- const auto confirmed = crl::guard(button, [=] {
- cSetConfigScale(scale);
- Local::writeSettings();
- Core::Restart();
- });
- const auto cancelled = crl::guard(button, [=](Fn<void()> close) {
- base::call_delayed(
- st::defaultSettingsSlider.duration,
- button,
- [=] { repeatSetScale(cConfigScale(), repeatSetScale); });
- close();
- });
- window->show(Ui::MakeConfirmBox({
- .text = tr::lng_settings_need_restart(),
- .confirmed = confirmed,
- .cancelled = cancelled,
- .confirmText = tr::lng_settings_restart_now(),
- }));
- } else if (scale != cConfigScale()) {
- cSetConfigScale(scale);
- Local::writeSettings();
- }
- };
- const auto shown = container->lifetime().make_state<bool>();
- const auto togglePreview = SetupScalePreview(window, slider);
- const auto toggleForScale = [=](int scale) {
- scale = cEvalScale(scale);
- const auto show = *shown
- ? ScalePreviewShow::Update
- : ScalePreviewShow::Show;
- *shown = true;
- for (auto i = 0; i != valuesCount; ++i) {
- if (values[i] <= scale
- && (i + 1 == valuesCount || values[i + 1] > scale)) {
- const auto x = (slider->width() * i) / (valuesCount - 1);
- togglePreview(show, scale, x);
- return;
- }
- }
- togglePreview(show, scale, slider->width() / 2);
- };
- const auto toggleHidePreview = [=] {
- togglePreview(ScalePreviewShow::Hide, 0, 0);
- *shown = false;
- };
- slider->setPseudoDiscrete(
- valuesCount,
- [=](int index) { return values[index]; },
- cConfigScale(),
- [=](int scale) { updateLabel(scale); toggleForScale(scale); },
- [=](int scale) { toggleHidePreview(); setScale(scale, setScale); });
- button->toggledValue(
- ) | rpl::map([](bool checked) {
- return checked ? style::kScaleAuto : cEvalScale(cConfigScale());
- }) | rpl::start_with_next([=](int scale) {
- setScale(scale, setScale);
- }, button->lifetime());
- if (!icon) {
- Ui::AddSkip(container, st::settingsThumbSkip);
- }
- }
- void SetupHelp(
- not_null<Window::SessionController*> controller,
- not_null<Ui::VerticalLayout*> container) {
- Ui::AddDivider(container);
- Ui::AddSkip(container);
- AddButtonWithIcon(
- container,
- tr::lng_settings_faq(),
- st::settingsButton,
- { &st::menuIconFaq }
- )->addClickHandler([=] {
- OpenFaq(controller);
- });
- AddButtonWithIcon(
- container,
- tr::lng_settings_features(),
- st::settingsButton,
- { &st::menuIconEmojiObjects }
- )->setClickedCallback([=] {
- UrlClickHandler::Open(tr::lng_telegram_features_url(tr::now));
- });
- const auto button = AddButtonWithIcon(
- container,
- tr::lng_settings_ask_question(),
- st::settingsButton,
- { &st::menuIconDiscussion });
- const auto requestId = button->lifetime().make_state<mtpRequestId>();
- button->lifetime().add([=] {
- if (*requestId) {
- controller->session().api().request(*requestId).cancel();
- }
- });
- button->addClickHandler([=] {
- const auto sure = crl::guard(button, [=] {
- if (*requestId) {
- return;
- }
- *requestId = controller->session().api().request(
- MTPhelp_GetSupport()
- ).done([=](const MTPhelp_Support &result) {
- *requestId = 0;
- result.match([&](const MTPDhelp_support &data) {
- auto &owner = controller->session().data();
- if (const auto user = owner.processUser(data.vuser())) {
- controller->showPeerHistory(user);
- }
- });
- }).fail([=] {
- *requestId = 0;
- }).send();
- });
- auto box = Ui::MakeConfirmBox({
- .text = tr::lng_settings_ask_sure(),
- .confirmed = sure,
- .cancelled = [=](Fn<void()> close) {
- OpenFaq(controller);
- close();
- },
- .confirmText = tr::lng_settings_ask_ok(),
- .cancelText = tr::lng_settings_faq_button(),
- .strictCancel = true,
- });
- controller->show(std::move(box));
- });
- }
- Main::Main(
- QWidget *parent,
- not_null<Window::SessionController*> controller)
- : Section(parent)
- , _controller(controller) {
- setupContent(controller);
- _controller->session().api().premium().reload();
- }
- rpl::producer<QString> Main::title() {
- return tr::lng_menu_settings();
- }
- void Main::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) {
- const auto &list = Core::App().domain().accounts();
- if (list.size() < Core::App().domain().maxAccounts()) {
- addAction(tr::lng_menu_add_account(tr::now), [=] {
- Core::App().domain().addActivated(MTP::Environment{});
- }, &st::menuIconAddAccount);
- }
- if (!_controller->session().supportMode()) {
- addAction(
- tr::lng_settings_information(tr::now),
- [=] { showOther(Information::Id()); },
- &st::menuIconEdit);
- }
- const auto window = &_controller->window();
- addAction({
- .text = tr::lng_settings_logout(tr::now),
- .handler = [=] { window->showLogoutConfirmation(); },
- .icon = &st::menuIconLeaveAttention,
- .isAttention = true,
- });
- }
- void Main::keyPressEvent(QKeyEvent *e) {
- crl::on_main(this, [=, text = e->text()]{
- CodesFeedString(_controller, text);
- });
- return Section::keyPressEvent(e);
- }
- void Main::setupContent(not_null<Window::SessionController*> controller) {
- const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
- content->add(object_ptr<Cover>(
- content,
- controller,
- controller->session().user()));
- SetupSections(controller, content, showOtherMethod());
- if (HasInterfaceScale()) {
- Ui::AddDivider(content);
- Ui::AddSkip(content);
- SetupInterfaceScale(&controller->window(), content);
- Ui::AddSkip(content);
- }
- SetupPremium(controller, content, showOtherMethod());
- SetupHelp(controller, content);
- Ui::ResizeFitChild(this, content);
- // If we load this in advance it won't jump when we open its' section.
- controller->session().api().cloudPassword().reload();
- controller->session().api().reloadContactSignupSilent();
- controller->session().api().sensitiveContent().reload();
- controller->session().api().globalPrivacy().reload();
- controller->session().data().cloudThemes().refresh();
- }
- void OpenFaq(base::weak_ptr<Window::SessionController> weak) {
- UrlClickHandler::Open(
- tr::lng_settings_faq_link(tr::now),
- QVariant::fromValue(ClickHandlerContext{
- .sessionWindow = weak,
- }));
- }
- } // namespace Settings
|