diff --git a/Telegram/SourceFiles/boxes/language_box.cpp b/Telegram/SourceFiles/boxes/language_box.cpp index 2471022acb..409ce10cee 100644 --- a/Telegram/SourceFiles/boxes/language_box.cpp +++ b/Telegram/SourceFiles/boxes/language_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/language_box.h" +#include "data/data_peer_values.h" #include "lang/lang_keys.h" #include "ui/boxes/choose_language_box.h" #include "ui/widgets/checkbox.h" @@ -24,8 +25,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/text/text_options.h" #include "ui/painter.h" #include "storage/localstorage.h" +#include "boxes/premium_preview_box.h" #include "boxes/translate_box.h" #include "ui/boxes/confirm_box.h" +#include "main/main_session.h" #include "mainwidget.h" #include "mainwindow.h" #include "core/application.h" @@ -33,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_cloud_manager.h" #include "settings/settings_common.h" #include "spellcheck/spellcheck_types.h" +#include "window/window_session_controller.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" #include "styles/style_info.h" @@ -1095,58 +1099,17 @@ Ui::ScrollToRequest Content::jump(int rows) { } // namespace +LanguageBox::LanguageBox(QWidget*, Window::SessionController *controller) +: _controller(controller) { +} + void LanguageBox::prepare() { addButton(tr::lng_box_ok(), [=] { closeBox(); }); setTitle(tr::lng_languages()); const auto topContainer = Ui::CreateChild(this); - Settings::AddSubsectionTitle( - topContainer, - tr::lng_translate_settings_subtitle()); - - const auto translateEnabled = Settings::AddButton( - topContainer, - tr::lng_translate_settings_show(), - st::settingsButtonNoIcon - )->toggleOn(rpl::single(Core::App().settings().translateButtonEnabled())); - - translateEnabled->toggledValue( - ) | rpl::filter([](bool checked) { - return (checked != Core::App().settings().translateButtonEnabled()); - }) | rpl::start_with_next([=](bool checked) { - Core::App().settings().setTranslateButtonEnabled(checked); - Core::App().saveSettingsDelayed(); - }, translateEnabled->lifetime()); - - using Languages = std::vector; - const auto translateSkipWrap = topContainer->add( - object_ptr>( - topContainer, - object_ptr(topContainer))); - translateSkipWrap->toggle( - translateEnabled->toggled(), - anim::type::normal); - translateSkipWrap->toggleOn(translateEnabled->toggledValue()); - const auto translateSkip = Settings::AddButtonWithLabel( - translateSkipWrap->entity(), - tr::lng_translate_settings_choose(), - Core::App().settings().skipTranslationLanguagesValue( - ) | rpl::map([](const Languages &list) { - return (list.size() > 1) - ? tr::lng_languages_count(tr::now, lt_count, list.size()) - : Ui::LanguageName(list.front()); - }), - st::settingsButtonNoIcon); - - translateSkip->setClickedCallback([=] { - Ui::BoxShow(this).showBox(Ui::EditSkipTranslationLanguages()); - }); - Settings::AddSkip(topContainer); - Settings::AddDividerText( - topContainer, - tr::lng_translate_settings_about()); - + setupTop(topContainer); const auto select = topContainer->add( object_ptr( topContainer, @@ -1210,6 +1173,86 @@ void LanguageBox::prepare() { }; } +void LanguageBox::setupTop(not_null container) { + if (!_controller) { + return; + } + const auto translateEnabled = Settings::AddButton( + container, + tr::lng_translate_settings_show(), + st::settingsButtonNoIcon + )->toggleOn( + rpl::single(Core::App().settings().translateButtonEnabled())); + + translateEnabled->toggledValue( + ) | rpl::filter([](bool checked) { + return (checked != Core::App().settings().translateButtonEnabled()); + }) | rpl::start_with_next([=](bool checked) { + Core::App().settings().setTranslateButtonEnabled(checked); + Core::App().saveSettingsDelayed(); + }, translateEnabled->lifetime()); + + using namespace rpl::mappers; + auto premium = Data::AmPremiumValue(&_controller->session()); + const auto translateChat = Settings::AddButton( + container, + tr::lng_translate_settings_chat(), + st::settingsButtonNoIconLocked + )->toggleOn(rpl::merge( + rpl::combine( + Core::App().settings().translateChatEnabledValue(), + rpl::duplicate(premium), + _1 && _2), + _translateChatTurnOff.events())); + std::move(premium) | rpl::start_with_next([=](bool value) { + translateChat->setToggleLocked(!value); + }, translateChat->lifetime()); + + translateChat->toggledValue( + ) | rpl::filter([=](bool checked) { + const auto premium = _controller->session().premium(); + if (checked && !premium) { + ShowPremiumPreviewToBuy( + _controller, + PremiumPreview::RealTimeTranslation); + _translateChatTurnOff.fire(false); + } + return premium + && (checked != Core::App().settings().translateChatEnabled()); + }) | rpl::start_with_next([=](bool checked) { + Core::App().settings().setTranslateChatEnabled(checked); + Core::App().saveSettingsDelayed(); + }, translateChat->lifetime()); + + using Languages = std::vector; + const auto translateSkipWrap = container->add( + object_ptr>( + container, + object_ptr(container))); + translateSkipWrap->toggle( + translateEnabled->toggled(), + anim::type::normal); + translateSkipWrap->toggleOn(translateEnabled->toggledValue()); + const auto translateSkip = Settings::AddButtonWithLabel( + translateSkipWrap->entity(), + tr::lng_translate_settings_choose(), + Core::App().settings().skipTranslationLanguagesValue( + ) | rpl::map([](const Languages &list) { + return (list.size() > 1) + ? tr::lng_languages_count(tr::now, lt_count, list.size()) + : Ui::LanguageName(list.front()); + }), + st::settingsButtonNoIcon); + + translateSkip->setClickedCallback([=] { + Ui::BoxShow(this).showBox(Ui::EditSkipTranslationLanguages()); + }); + Settings::AddSkip(container); + Settings::AddDividerText( + container, + tr::lng_translate_settings_about()); +} + void LanguageBox::keyPressEvent(QKeyEvent *e) { const auto key = e->key(); if (key == Qt::Key_Escape) { @@ -1241,11 +1284,12 @@ void LanguageBox::setInnerFocus() { _setInnerFocus(); } -base::binary_guard LanguageBox::Show() { +base::binary_guard LanguageBox::Show(Window::SessionController *controller) { auto result = base::binary_guard(); auto &manager = Lang::CurrentCloudManager(); if (manager.languageList().empty()) { + const auto weak = base::make_weak(controller); auto guard = std::make_shared( result.make_guard()); auto lifetime = std::make_shared(); @@ -1258,11 +1302,11 @@ base::binary_guard LanguageBox::Show() { base::take(lifetime)->destroy(); } if (show) { - Ui::show(Box()); + Ui::show(Box(weak.get())); } }, *lifetime); } else { - Ui::show(Box()); + Ui::show(Box(controller)); } manager.requestLanguageList(); diff --git a/Telegram/SourceFiles/boxes/language_box.h b/Telegram/SourceFiles/boxes/language_box.h index 0727ad58aa..5e500b0bbd 100644 --- a/Telegram/SourceFiles/boxes/language_box.h +++ b/Telegram/SourceFiles/boxes/language_box.h @@ -16,16 +16,20 @@ struct LanguageId; namespace Ui { class MultiSelect; struct ScrollToRequest; +class VerticalLayout; } // namespace Ui +namespace Window { +class SessionController; +} // namespace Window + class LanguageBox : public Ui::BoxContent { public: - LanguageBox(QWidget*) { - } + LanguageBox(QWidget*, Window::SessionController *controller); void setInnerFocus() override; - static base::binary_guard Show(); + static base::binary_guard Show(Window::SessionController *controller); protected: void prepare() override; @@ -35,8 +39,11 @@ protected: private: using Languages = Lang::CloudManager::Languages; - int rowsInPage() const; + void setupTop(not_null container); + [[nodiscard]] int rowsInPage() const; + Window::SessionController *_controller = nullptr; + rpl::event_stream _translateChatTurnOff; Fn _setInnerFocus; Fn _jump; diff --git a/Telegram/SourceFiles/boxes/premium_preview_box.h b/Telegram/SourceFiles/boxes/premium_preview_box.h index 3d16349b6c..0bf439d29b 100644 --- a/Telegram/SourceFiles/boxes/premium_preview_box.h +++ b/Telegram/SourceFiles/boxes/premium_preview_box.h @@ -62,7 +62,7 @@ void ShowPremiumPreviewBox( void ShowPremiumPreviewToBuy( not_null controller, PremiumPreview section, - Fn hiddenCallback); + Fn hiddenCallback = nullptr); void PremiumUnavailableBox(not_null box); diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 7fe8068277..d19dd419e5 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -384,18 +384,22 @@ void Application::showAccount(not_null account) { _lastActivePrimaryWindow = separate; separate->activate(); } else if (const auto last = activePrimaryWindow()) { - for (auto &[key, window] : _primaryWindows) { - if (window.get() == last && key != account.get()) { - auto found = std::move(window); - _primaryWindows.remove(key); - _primaryWindows.emplace(account, std::move(found)); - break; - } - } last->showAccount(account); } } +void Application::checkWindowAccount(not_null window) { + const auto account = window->maybeAccount(); + for (auto &[key, existing] : _primaryWindows) { + if (existing.get() == window && key != account) { + auto found = std::move(existing); + _primaryWindows.remove(key); + _primaryWindows.emplace(account, std::move(found)); + break; + } + } +} + void Application::showOpenGLCrashNotification() { const auto enable = [=] { Ui::GL::ForceDisable(false); diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index 4c24192cee..d4ed245a4f 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -181,6 +181,7 @@ public: void checkSystemDarkMode(); [[nodiscard]] bool isActiveForTrayMenu() const; void closeChatFromWindows(not_null peer); + void checkWindowAccount(not_null window); void activate(); // Media view interface. diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index 34b02828ac..2e2034e025 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -113,9 +113,9 @@ bool ShowTheme( return true; } -void ShowLanguagesBox() { +void ShowLanguagesBox(Window::SessionController *controller) { static auto Guard = base::binary_guard(); - Guard = LanguageBox::Show(); + Guard = LanguageBox::Show(controller); } bool SetLanguage( @@ -123,7 +123,7 @@ bool SetLanguage( const Match &match, const QVariant &context) { if (match->capturedView(1).isEmpty()) { - ShowLanguagesBox(); + ShowLanguagesBox(controller); } else { const auto languageId = match->captured(2); Lang::CurrentCloudManager().switchWithWarning(languageId); @@ -468,18 +468,12 @@ bool ResolveSettings( Window::SessionController *controller, const Match &match, const QVariant &context) { - if (!controller) { - return false; - } - controller->window().activate(); const auto section = match->captured(1).mid(1).toLower(); - const auto type = [&]() -> std::optional<::Settings::Type> { if (section == u"language"_q) { - ShowLanguagesBox(); + ShowLanguagesBox(controller); return {}; } else if (section == u"devices"_q) { - controller->session().api().authorizations().reload(); return ::Settings::Sessions::Id(); } else if (section == u"folders"_q) { return ::Settings::Folders::Id(); @@ -498,6 +492,11 @@ bool ResolveSettings( }(); if (type.has_value()) { + if (!controller) { + return false; + } else if (*type == ::Settings::Sessions::Id()) { + controller->session().api().authorizations().reload(); + } controller->showSettings(*type); controller->window().activate(); } diff --git a/Telegram/SourceFiles/history/view/history_view_translate_tracker.cpp b/Telegram/SourceFiles/history/view/history_view_translate_tracker.cpp index 716a11dfa4..7017ffe46e 100644 --- a/Telegram/SourceFiles/history/view/history_view_translate_tracker.cpp +++ b/Telegram/SourceFiles/history/view/history_view_translate_tracker.cpp @@ -57,7 +57,11 @@ void TranslateTracker::setup() { const auto session = &_history->session(); peer->updateFull(); - _trackingLanguage = Data::AmPremiumValue(&_history->session()); + using namespace rpl::mappers; + _trackingLanguage = rpl::combine( + Data::AmPremiumValue(&_history->session()), + Core::App().settings().translateChatEnabledValue(), + _1 && _2); _trackingLanguage.value( ) | rpl::start_with_next([=](bool tracking) { diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 33788e077a..e6f4ba5c66 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1278,7 +1278,7 @@ bool MainWidget::showHistoryInDifferentWindow( } else if (isPrimary()) { const auto primary = Core::App().separateWindowForAccount( &peer->account()); - if (primary != &_controller->window()) { + if (primary && primary != &_controller->window()) { primary->sessionController()->showPeerHistory( peerId, params, diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index ebf77cdb6b..9c91a5aef7 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -22,6 +22,14 @@ settingsButtonLight: SettingsButton(settingsButton) { settingsButtonNoIcon: SettingsButton(settingsButton) { padding: margins(22px, 10px, 22px, 8px); } +settingsButtonNoIconLocked : SettingsButton(settingsButtonNoIcon) { + toggle: Toggle(infoProfileToggle) { + lockIcon: icon {{ "info/info_rights_lock", menuIconFg }}; + } + toggleOver: Toggle(infoProfileToggleOver) { + lockIcon: icon {{ "info/info_rights_lock", menuIconFgOver }}; + } +} settingsButtonActive: SettingsButton(infoMainButton, settingsButton) { } settingsAttentionButton: SettingsButton(settingsButtonNoIcon) { diff --git a/Telegram/SourceFiles/settings/settings_intro.cpp b/Telegram/SourceFiles/settings/settings_intro.cpp index e067f47fc6..1facf1e3ae 100644 --- a/Telegram/SourceFiles/settings/settings_intro.cpp +++ b/Telegram/SourceFiles/settings/settings_intro.cpp @@ -63,7 +63,7 @@ object_ptr CreateIntroSettings( AddDivider(result); AddSkip(result); - SetupLanguageButton(result, false); + SetupLanguageButton(window, result, false); SetupConnectionType(window, &window->account(), result); AddSkip(result); if (HasUpdate()) { diff --git a/Telegram/SourceFiles/settings/settings_main.cpp b/Telegram/SourceFiles/settings/settings_main.cpp index 8485fff1a3..039a276d3e 100644 --- a/Telegram/SourceFiles/settings/settings_main.cpp +++ b/Telegram/SourceFiles/settings/settings_main.cpp @@ -251,6 +251,7 @@ void Cover::refreshUsernameGeometry(int newWidth) { } // namespace void SetupLanguageButton( + not_null window, not_null container, bool icon) { const auto button = AddButtonWithLabel( @@ -269,7 +270,7 @@ void SetupLanguageButton( if ((m & Qt::ShiftModifier) && (m & Qt::AltModifier)) { Lang::CurrentCloudManager().switchToLanguage({ u"#custom"_q }); } else { - *guard = LanguageBox::Show(); + *guard = LanguageBox::Show(window->sessionController()); } }); } @@ -373,7 +374,7 @@ void SetupSections( Calls::Id(), { &st::settingsIconCalls, kIconGreen }); - SetupLanguageButton(container); + SetupLanguageButton(&controller->window(), container); if (controller->session().premiumPossible()) { AddSkip(container); diff --git a/Telegram/SourceFiles/settings/settings_main.h b/Telegram/SourceFiles/settings/settings_main.h index 9f00296ad4..4c1529d7d7 100644 --- a/Telegram/SourceFiles/settings/settings_main.h +++ b/Telegram/SourceFiles/settings/settings_main.h @@ -21,6 +21,7 @@ class VerticalLayout; namespace Settings { void SetupLanguageButton( + not_null window, not_null container, bool icon = true); bool HasInterfaceScale(); diff --git a/Telegram/SourceFiles/window/window_controller.cpp b/Telegram/SourceFiles/window/window_controller.cpp index b9ea7fc30b..25e62283fe 100644 --- a/Telegram/SourceFiles/window/window_controller.cpp +++ b/Telegram/SourceFiles/window/window_controller.cpp @@ -86,6 +86,7 @@ void Controller::showAccount( : 0; _accountLifetime.destroy(); _account = account; + Core::App().checkWindowAccount(this); const auto updateOnlineOfPrevSesssion = crl::guard(_account, [=] { if (!prevSessionUniqueId) { diff --git a/Telegram/lib_spellcheck b/Telegram/lib_spellcheck index 46385c3545..55ed1489ff 160000 --- a/Telegram/lib_spellcheck +++ b/Telegram/lib_spellcheck @@ -1 +1 @@ -Subproject commit 46385c35458d41ce589a75db51f320842794e31a +Subproject commit 55ed1489ffac0b60adbd427c2b76be1ce55194e7