From ddfcf9f1df51abd96be8259d9e0852cd74add5f4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 7 Feb 2023 18:38:10 +0400 Subject: [PATCH] Don't allow empty "Do Not Translate" list. --- Telegram/SourceFiles/boxes/translate_box.cpp | 33 +++++++++++++++++-- .../ui/boxes/choose_language_box.cpp | 29 +++++++++++++--- .../ui/boxes/choose_language_box.h | 3 +- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/boxes/translate_box.cpp b/Telegram/SourceFiles/boxes/translate_box.cpp index 07af0a754..805632556 100644 --- a/Telegram/SourceFiles/boxes/translate_box.cpp +++ b/Telegram/SourceFiles/boxes/translate_box.cpp @@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/boxes/choose_language_box.h" #include "ui/effects/loading_element.h" #include "ui/layers/generic_box.h" +#include "ui/toasts/common_toasts.h" #include "ui/painter.h" #include "ui/widgets/buttons.h" #include "ui/widgets/labels.h" @@ -39,6 +40,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { namespace { +constexpr auto kSkipAtLeastOneDuration = 3 * crl::time(1000); + class ShowButton final : public RpWidget { public: ShowButton(not_null parent); @@ -285,12 +288,36 @@ bool SkipTranslate(TextWithEntities textWithEntities) { object_ptr EditSkipTranslationLanguages() { auto title = tr::lng_translate_settings_choose(); - return Box(ChooseLanguageBox, std::move(title), [=]( + const auto selected = std::make_shared>( + Core::App().settings().skipTranslationLanguages()); + const auto weak = std::make_shared>(); + const auto check = [=](LanguageId id) { + const auto already = ranges::contains(*selected, id); + if (already) { + selected->erase(ranges::remove(*selected, id), selected->end()); + } else { + selected->push_back(id); + } + if (already && selected->empty()) { + if (const auto strong = weak->data()) { + Ui::ShowMultilineToast({ + .parentOverride = BoxShow(strong).toastParent(), + .text = { tr::lng_translate_settings_one(tr::now) }, + .duration = kSkipAtLeastOneDuration, + }); + } + return false; + } + return true; + }; + auto result = Box(ChooseLanguageBox, std::move(title), [=]( std::vector &&list) { Core::App().settings().setSkipTranslationLanguages( std::move(list)); Core::App().saveSettingsDelayed(); - }, Core::App().settings().skipTranslationLanguages(), true); + }, *selected, true, check); + *weak = result.data(); + return result; } object_ptr ChooseTranslateToBox( @@ -310,7 +337,7 @@ object_ptr ChooseTranslateToBox( Core::App().settings().setTranslateTo(id); Core::App().saveSettingsDelayed(); callback(id); - }, selected, false); + }, selected, false, nullptr); } LanguageId ChooseTranslateTo(not_null history) { diff --git a/Telegram/SourceFiles/ui/boxes/choose_language_box.cpp b/Telegram/SourceFiles/ui/boxes/choose_language_box.cpp index 6f90d8f73..e4bea1cc7 100644 --- a/Telegram/SourceFiles/ui/boxes/choose_language_box.cpp +++ b/Telegram/SourceFiles/ui/boxes/choose_language_box.cpp @@ -266,7 +266,8 @@ void ChooseLanguageBox( rpl::producer title, Fn)> callback, std::vector selected, - bool multiselect) { + bool multiselect, + Fn toggleCheck) { box->setMinHeight(st::boxWidth); box->setMaxHeight(st::boxWidth); box->setTitle(std::move(title)); @@ -294,6 +295,14 @@ void ChooseLanguageBox( }); return list; }(); + struct ToggleOne { + LanguageId id; + bool selected = false; + }; + struct State { + rpl::event_stream toggles; + }; + const auto state = box->lifetime().make_state(); auto rows = std::vector*>>(); rows.reserve(langs.size()); for (const auto &id : langs) { @@ -302,9 +311,21 @@ void ChooseLanguageBox( container, object_ptr(container, id))); if (multiselect) { - button->entity()->toggleOn( - rpl::single(ranges::contains(selected, id)), - false); + button->entity()->toggleOn(rpl::single( + ranges::contains(selected, id) + ) | rpl::then(state->toggles.events( + ) | rpl::filter([=](ToggleOne one) { + return one.id == id; + }) | rpl::map([=](ToggleOne one) { + return one.selected; + }))); + + button->entity()->toggledChanges( + ) | rpl::start_with_next([=](bool value) { + if (toggleCheck && !toggleCheck(id)) { + state->toggles.fire({ .id = id, .selected = !value }); + } + }, button->lifetime()); } else { button->entity()->setClickedCallback([=] { callback({ id }); diff --git a/Telegram/SourceFiles/ui/boxes/choose_language_box.h b/Telegram/SourceFiles/ui/boxes/choose_language_box.h index f33af2b2b..dd96332ae 100644 --- a/Telegram/SourceFiles/ui/boxes/choose_language_box.h +++ b/Telegram/SourceFiles/ui/boxes/choose_language_box.h @@ -30,6 +30,7 @@ void ChooseLanguageBox( rpl::producer title, Fn)> callback, std::vector selected, - bool multiselect); + bool multiselect, + Fn toggleCheck); } // namespace Ui