Add "Translate Entire Chat" button to Settings.

This commit is contained in:
John Preston 2023-01-30 18:01:10 +04:00
parent f5be551ff8
commit be71139515
14 changed files with 148 additions and 78 deletions

View File

@ -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<Ui::VerticalLayout>(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<LanguageId>;
const auto translateSkipWrap = topContainer->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
topContainer,
object_ptr<Ui::VerticalLayout>(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<Ui::MultiSelect>(
topContainer,
@ -1210,6 +1173,86 @@ void LanguageBox::prepare() {
};
}
void LanguageBox::setupTop(not_null<Ui::VerticalLayout*> 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<LanguageId>;
const auto translateSkipWrap = container->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
container,
object_ptr<Ui::VerticalLayout>(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<base::binary_guard>(
result.make_guard());
auto lifetime = std::make_shared<rpl::lifetime>();
@ -1258,11 +1302,11 @@ base::binary_guard LanguageBox::Show() {
base::take(lifetime)->destroy();
}
if (show) {
Ui::show(Box<LanguageBox>());
Ui::show(Box<LanguageBox>(weak.get()));
}
}, *lifetime);
} else {
Ui::show(Box<LanguageBox>());
Ui::show(Box<LanguageBox>(controller));
}
manager.requestLanguageList();

View File

@ -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<Ui::VerticalLayout*> container);
[[nodiscard]] int rowsInPage() const;
Window::SessionController *_controller = nullptr;
rpl::event_stream<bool> _translateChatTurnOff;
Fn<void()> _setInnerFocus;
Fn<Ui::ScrollToRequest(int rows)> _jump;

View File

@ -62,7 +62,7 @@ void ShowPremiumPreviewBox(
void ShowPremiumPreviewToBuy(
not_null<Window::SessionController*> controller,
PremiumPreview section,
Fn<void()> hiddenCallback);
Fn<void()> hiddenCallback = nullptr);
void PremiumUnavailableBox(not_null<Ui::GenericBox*> box);

View File

@ -384,18 +384,22 @@ void Application::showAccount(not_null<Main::Account*> 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::Controller*> 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);

View File

@ -181,6 +181,7 @@ public:
void checkSystemDarkMode();
[[nodiscard]] bool isActiveForTrayMenu() const;
void closeChatFromWindows(not_null<PeerData*> peer);
void checkWindowAccount(not_null<Window::Controller*> window);
void activate();
// Media view interface.

View File

@ -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();
}

View File

@ -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) {

View File

@ -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,

View File

@ -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) {

View File

@ -63,7 +63,7 @@ object_ptr<Ui::RpWidget> CreateIntroSettings(
AddDivider(result);
AddSkip(result);
SetupLanguageButton(result, false);
SetupLanguageButton(window, result, false);
SetupConnectionType(window, &window->account(), result);
AddSkip(result);
if (HasUpdate()) {

View File

@ -251,6 +251,7 @@ void Cover::refreshUsernameGeometry(int newWidth) {
} // namespace
void SetupLanguageButton(
not_null<Window::Controller*> window,
not_null<Ui::VerticalLayout*> 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);

View File

@ -21,6 +21,7 @@ class VerticalLayout;
namespace Settings {
void SetupLanguageButton(
not_null<Window::Controller*> window,
not_null<Ui::VerticalLayout*> container,
bool icon = true);
bool HasInterfaceScale();

View File

@ -86,6 +86,7 @@ void Controller::showAccount(
: 0;
_accountLifetime.destroy();
_account = account;
Core::App().checkWindowAccount(this);
const auto updateOnlineOfPrevSesssion = crl::guard(_account, [=] {
if (!prevSessionUniqueId) {

@ -1 +1 @@
Subproject commit 46385c35458d41ce589a75db51f320842794e31a
Subproject commit 55ed1489ffac0b60adbd427c2b76be1ce55194e7