mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-31 06:26:18 +00:00
Don't offer translate from / to the same language.
This commit is contained in:
@@ -11,6 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "core/core_settings.h"
|
||||
#include "core/ui_integration.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "history/history.h"
|
||||
#include "lang/lang_instance.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
@@ -96,9 +98,15 @@ void TranslateBox(
|
||||
box->addButton(tr::lng_box_ok(), [=] { box->closeBox(); });
|
||||
const auto container = box->verticalLayout();
|
||||
|
||||
auto id = Core::App().settings().translateToValue();
|
||||
const auto api = box->lifetime().make_state<MTP::Sender>(
|
||||
&peer->session().mtp());
|
||||
struct State {
|
||||
State(not_null<Main::Session*> session) : api(&session->mtp()) {
|
||||
}
|
||||
|
||||
MTP::Sender api;
|
||||
rpl::variable<LanguageId> to;
|
||||
};
|
||||
const auto state = box->lifetime().make_state<State>(&peer->session());
|
||||
state->to = ChooseTranslateTo(peer->owner().history(peer));
|
||||
|
||||
text.entities = ranges::views::all(
|
||||
text.entities
|
||||
@@ -174,10 +182,10 @@ void TranslateBox(
|
||||
const auto padding = st::settingsSubsectionTitlePadding;
|
||||
const auto subtitle = Settings::AddSubsectionTitle(
|
||||
container,
|
||||
rpl::duplicate(id) | rpl::map(LanguageName));
|
||||
state->to.value() | rpl::map(LanguageName));
|
||||
|
||||
// Workaround.
|
||||
rpl::duplicate(id) | rpl::start_with_next([=] {
|
||||
state->to.value() | rpl::start_with_next([=] {
|
||||
subtitle->resizeToWidth(container->width()
|
||||
- padding.left()
|
||||
- padding.right());
|
||||
@@ -197,7 +205,7 @@ void TranslateBox(
|
||||
box,
|
||||
st::aboutLabel,
|
||||
std::min(original->entity()->height() / lineHeight, kMaxLines),
|
||||
rpl::duplicate(id) | rpl::map([=](LanguageId id) {
|
||||
state->to.value() | rpl::map([=](LanguageId id) {
|
||||
return id.locale().textDirection() == Qt::RightToLeft;
|
||||
}))));
|
||||
|
||||
@@ -210,7 +218,7 @@ void TranslateBox(
|
||||
const auto send = [=](LanguageId to) {
|
||||
loading->show(anim::type::instant);
|
||||
translated->hide(anim::type::instant);
|
||||
api->request(MTPmessages_TranslateText(
|
||||
state->api.request(MTPmessages_TranslateText(
|
||||
MTP_flags(flags),
|
||||
msgId ? peer->input : MTP_inputPeerEmpty(),
|
||||
(msgId
|
||||
@@ -221,7 +229,7 @@ void TranslateBox(
|
||||
: MTP_vector<MTPTextWithEntities>(1, MTP_textWithEntities(
|
||||
MTP_string(text.text),
|
||||
MTP_vector<MTPMessageEntity>()))),
|
||||
MTP_string(to.locale().name().mid(0, 2))
|
||||
MTP_string(to.twoLetterCode())
|
||||
)).done([=](const MTPmessages_TranslatedText &result) {
|
||||
const auto &data = result.data();
|
||||
const auto &list = data.vresult().v;
|
||||
@@ -232,13 +240,15 @@ void TranslateBox(
|
||||
showText(tr::lng_translate_box_error(tr::now));
|
||||
}).send();
|
||||
};
|
||||
std::move(id) | rpl::start_with_next(send, box->lifetime());
|
||||
state->to.value() | rpl::start_with_next(send, box->lifetime());
|
||||
|
||||
box->addLeftButton(tr::lng_settings_language(), [=] {
|
||||
if (loading->toggled()) {
|
||||
return;
|
||||
}
|
||||
Ui::BoxShow(box).showBox(ChooseTranslateToBox());
|
||||
Ui::BoxShow(box).showBox(ChooseTranslateToBox(
|
||||
state->to.current(),
|
||||
crl::guard(box, [=](LanguageId id) { state->to = id; })));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -283,17 +293,50 @@ object_ptr<BoxContent> EditSkipTranslationLanguages() {
|
||||
}, Core::App().settings().skipTranslationLanguages(), true);
|
||||
}
|
||||
|
||||
object_ptr<BoxContent> ChooseTranslateToBox() {
|
||||
const auto selected = std::vector<LanguageId>{
|
||||
object_ptr<BoxContent> ChooseTranslateToBox(
|
||||
LanguageId bringUp,
|
||||
Fn<void(LanguageId)> callback) {
|
||||
auto selected = std::vector<LanguageId>{
|
||||
Core::App().settings().translateTo(),
|
||||
};
|
||||
if (bringUp && bringUp != selected.front()) {
|
||||
selected.push_back(bringUp);
|
||||
}
|
||||
return Box(ChooseLanguageBox, tr::lng_languages(), [=](
|
||||
const std::vector<LanguageId> &ids) {
|
||||
Expects(!ids.empty());
|
||||
|
||||
Core::App().settings().setTranslateTo(ids.front());
|
||||
const auto id = ids.front();
|
||||
Core::App().settings().setTranslateTo(id);
|
||||
Core::App().saveSettingsDelayed();
|
||||
callback(id);
|
||||
}, selected, false);
|
||||
}
|
||||
|
||||
LanguageId ChooseTranslateTo(not_null<History*> history) {
|
||||
return ChooseTranslateTo(history->translateOfferedFrom());
|
||||
}
|
||||
|
||||
LanguageId ChooseTranslateTo(LanguageId offeredFrom) {
|
||||
auto &settings = Core::App().settings();
|
||||
return ChooseTranslateTo(
|
||||
offeredFrom,
|
||||
settings.translateTo(),
|
||||
settings.skipTranslationLanguages());
|
||||
}
|
||||
|
||||
LanguageId ChooseTranslateTo(
|
||||
not_null<History*> history,
|
||||
LanguageId savedTo,
|
||||
const std::vector<LanguageId> &skip) {
|
||||
return ChooseTranslateTo(history->translateOfferedFrom(), savedTo, skip);
|
||||
}
|
||||
|
||||
LanguageId ChooseTranslateTo(
|
||||
LanguageId offeredFrom,
|
||||
LanguageId savedTo,
|
||||
const std::vector<LanguageId> &skip) {
|
||||
return (offeredFrom != savedTo) ? savedTo : skip.front();
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "base/object_ptr.h"
|
||||
|
||||
class History;
|
||||
class PeerData;
|
||||
struct LanguageId;
|
||||
|
||||
@@ -27,6 +28,19 @@ void TranslateBox(
|
||||
[[nodiscard]] bool SkipTranslate(TextWithEntities textWithEntities);
|
||||
|
||||
[[nodiscard]] object_ptr<BoxContent> EditSkipTranslationLanguages();
|
||||
[[nodiscard]] object_ptr<BoxContent> ChooseTranslateToBox();
|
||||
[[nodiscard]] object_ptr<BoxContent> ChooseTranslateToBox(
|
||||
LanguageId bringUp,
|
||||
Fn<void(LanguageId)> callback);
|
||||
|
||||
[[nodiscard]] LanguageId ChooseTranslateTo(not_null<History*> history);
|
||||
[[nodiscard]] LanguageId ChooseTranslateTo(LanguageId offeredFrom);
|
||||
[[nodiscard]] LanguageId ChooseTranslateTo(
|
||||
not_null<History*> history,
|
||||
LanguageId savedTo,
|
||||
const std::vector<LanguageId> &skip);
|
||||
[[nodiscard]] LanguageId ChooseTranslateTo(
|
||||
LanguageId offeredFrom,
|
||||
LanguageId savedTo,
|
||||
const std::vector<LanguageId> &skip);
|
||||
|
||||
} // namespace Ui
|
||||
|
@@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "spellcheck/spellcheck_types.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/boxes/choose_language_box.h" // EditSkipTranslationLanguages.
|
||||
#include "ui/layers/box_content.h"
|
||||
@@ -294,14 +293,6 @@ void TranslateBar::setup(not_null<History*> history) {
|
||||
: Core::App().settings().translateTo());
|
||||
});
|
||||
|
||||
Core::App().settings().translateToValue(
|
||||
) | rpl::filter([=](LanguageId should) {
|
||||
const auto now = history->translatedTo();
|
||||
return now && (now != should);
|
||||
}) | rpl::start_with_next([=](LanguageId should) {
|
||||
translateTo(should);
|
||||
}, _wrap.lifetime());
|
||||
|
||||
const auto label = Ui::CreateChild<Ui::FlatLabel>(
|
||||
button,
|
||||
st::historyTranslateLabel);
|
||||
@@ -343,8 +334,34 @@ void TranslateBar::setup(not_null<History*> history) {
|
||||
updateLabelGeometry();
|
||||
}, lifetime());
|
||||
|
||||
rpl::combine(
|
||||
_overridenTo = history->translatedTo();
|
||||
_to = rpl::combine(
|
||||
Core::App().settings().translateToValue(),
|
||||
Core::App().settings().skipTranslationLanguagesValue(),
|
||||
history->session().changes().historyFlagsValue(
|
||||
history,
|
||||
Data::HistoryUpdate::Flag::TranslateFrom),
|
||||
_overridenTo.value()
|
||||
) | rpl::map([=](
|
||||
LanguageId to,
|
||||
const std::vector<LanguageId> &skip,
|
||||
const auto &,
|
||||
LanguageId overridenTo) {
|
||||
return overridenTo
|
||||
? overridenTo
|
||||
: Ui::ChooseTranslateTo(history, to, skip);
|
||||
}) | rpl::distinct_until_changed();
|
||||
|
||||
_to.value(
|
||||
) | rpl::filter([=](LanguageId should) {
|
||||
const auto now = history->translatedTo();
|
||||
return now && (now != should);
|
||||
}) | rpl::start_with_next([=](LanguageId should) {
|
||||
translateTo(should);
|
||||
}, _wrap.lifetime());
|
||||
|
||||
rpl::combine(
|
||||
_to.value(),
|
||||
history->session().changes().historyFlagsValue(
|
||||
history,
|
||||
(Data::HistoryUpdate::Flag::TranslatedTo
|
||||
@@ -352,16 +369,17 @@ void TranslateBar::setup(not_null<History*> history) {
|
||||
history->session().changes().peerFlagsValue(
|
||||
history->peer,
|
||||
Data::PeerUpdate::Flag::TranslationDisabled)
|
||||
) | rpl::map([=](LanguageId to, const auto&, const auto&) {
|
||||
) | rpl::map([=](
|
||||
LanguageId to,
|
||||
const auto&,
|
||||
const auto&) {
|
||||
using Flag = PeerData::TranslationFlag;
|
||||
return (history->peer->translationFlag() != Flag::Enabled)
|
||||
? rpl::single(QString())
|
||||
: history->translatedTo()
|
||||
? tr::lng_translate_show_original()
|
||||
: history->translateOfferedFrom()
|
||||
? tr::lng_translate_bar_to(
|
||||
lt_name,
|
||||
rpl::single(Ui::LanguageName(to)))
|
||||
? Ui::TranslateBarTo(to)
|
||||
: rpl::single(QString());
|
||||
}) | rpl::flatten_latest(
|
||||
) | rpl::distinct_until_changed(
|
||||
@@ -408,20 +426,25 @@ void TranslateBar::showMenu(base::unique_qptr<Ui::PopupMenu> menu) {
|
||||
_menu = std::move(menu);
|
||||
_menu->setForcedOrigin(Ui::PanelAnimation::Origin::TopRight);
|
||||
|
||||
const auto guard = Ui::MakeWeak(&_wrap);
|
||||
const auto now = _history->translatedTo();
|
||||
const auto to = now ? now : Ui::ChooseTranslateTo(_history);
|
||||
const auto weak = base::make_weak(_controller);
|
||||
const auto chooseCallback = [=] {
|
||||
if (const auto strong = weak.get()) {
|
||||
strong->show(Ui::ChooseTranslateToBox());
|
||||
strong->show(Ui::ChooseTranslateToBox(
|
||||
to,
|
||||
crl::guard(guard, [=](LanguageId id) { _overridenTo = id; })
|
||||
));
|
||||
}
|
||||
};
|
||||
_menu->addAction(MakeTranslateToItem(
|
||||
_menu->menu(),
|
||||
Ui::LanguageName(Core::App().settings().translateTo()),
|
||||
Ui::LanguageName(to ? to : Ui::ChooseTranslateTo(_history)),
|
||||
chooseCallback));
|
||||
_menu->addSeparator();
|
||||
const auto history = _history;
|
||||
if (const auto translateOfferedFrom = _history->translateOfferedFrom()) {
|
||||
const auto name = Ui::LanguageName(translateOfferedFrom);
|
||||
const auto addToIgnoreList = [=] {
|
||||
showSettingsToast(history->peer, translateOfferedFrom);
|
||||
|
||||
@@ -436,7 +459,7 @@ void TranslateBar::showMenu(base::unique_qptr<Ui::PopupMenu> menu) {
|
||||
Core::App().saveSettingsDelayed();
|
||||
};
|
||||
_menu->addAction(
|
||||
tr::lng_translate_menu_dont(tr::now, lt_name, name),
|
||||
Ui::TranslateMenuDont(tr::now, translateOfferedFrom),
|
||||
addToIgnoreList,
|
||||
&st::menuIconBlock);
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#pragma once
|
||||
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "spellcheck/spellcheck_types.h"
|
||||
|
||||
class History;
|
||||
struct LanguageId;
|
||||
@@ -68,6 +69,8 @@ private:
|
||||
std::unique_ptr<Ui::PlainShadow> _shadow;
|
||||
Fn<QRect(QRect)> _shadowGeometryPostprocess;
|
||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||
rpl::variable<LanguageId> _overridenTo;
|
||||
rpl::variable<LanguageId> _to;
|
||||
bool _shouldBeShown = false;
|
||||
bool _forceHidden = false;
|
||||
|
||||
|
@@ -234,7 +234,7 @@ void TranslateTracker::requestSome() {
|
||||
peer->input,
|
||||
MTP_vector<MTPint>(list),
|
||||
MTPVector<MTPTextWithEntities>(),
|
||||
MTP_string(to.locale().name().mid(0, 2))
|
||||
MTP_string(to.twoLetterCode())
|
||||
)).done([=](const MTPmessages_TranslatedText &result) {
|
||||
requestDone(to, result.data().vresult().v);
|
||||
}).fail([=] {
|
||||
|
@@ -22,7 +22,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
const auto kLanguageNamePrefix = "cloud_lng_passport_in_";
|
||||
const auto kLanguageNamePrefix = "cloud_lng_language_";
|
||||
const auto kTranslateToPrefix = "cloud_lng_translate_to_";
|
||||
|
||||
[[nodiscard]] std::vector<LanguageId> TranslationLanguagesList() {
|
||||
// If adding some languages here you need to check that it is
|
||||
@@ -214,12 +215,13 @@ QString LanguageNameTranslated(const QString &twoLetterCode) {
|
||||
kLanguageNamePrefix + twoLetterCode.toUtf8());
|
||||
}
|
||||
|
||||
QString LanguageNameLocal(LanguageId id) {
|
||||
return QLocale::languageToString(id.language());
|
||||
}
|
||||
|
||||
QString LanguageName(LanguageId id) {
|
||||
const auto code = id.locale().name().toLower().mid(0, 2);
|
||||
const auto translated = LanguageNameTranslated(code);
|
||||
return translated.isEmpty()
|
||||
? QLocale::languageToString(id.locale().language())
|
||||
: translated;
|
||||
const auto translated = LanguageNameTranslated(id.twoLetterCode());
|
||||
return translated.isEmpty() ? LanguageNameLocal(id) : translated;
|
||||
}
|
||||
|
||||
QString LanguageNameNative(LanguageId id) {
|
||||
@@ -236,6 +238,29 @@ QString LanguageNameNative(LanguageId id) {
|
||||
}
|
||||
}
|
||||
|
||||
rpl::producer<QString> TranslateBarTo(LanguageId id) {
|
||||
const auto translated = Lang::GetNonDefaultValue(
|
||||
kTranslateToPrefix + id.twoLetterCode().toUtf8());
|
||||
return (translated.isEmpty()
|
||||
? tr::lng_translate_bar_to_other
|
||||
: tr::lng_translate_bar_to)(
|
||||
lt_name,
|
||||
rpl::single(translated.isEmpty()
|
||||
? LanguageNameLocal(id)
|
||||
: translated));
|
||||
}
|
||||
|
||||
QString TranslateMenuDont(tr::now_t, LanguageId id) {
|
||||
const auto translated = Lang::GetNonDefaultValue(
|
||||
kTranslateToPrefix + id.twoLetterCode().toUtf8());
|
||||
return (translated.isEmpty()
|
||||
? tr::lng_translate_menu_dont_other
|
||||
: tr::lng_translate_menu_dont)(
|
||||
tr::now,
|
||||
lt_name,
|
||||
translated.isEmpty() ? LanguageNameLocal(id) : translated);
|
||||
}
|
||||
|
||||
void ChooseLanguageBox(
|
||||
not_null<GenericBox*> box,
|
||||
rpl::producer<QString> title,
|
||||
@@ -256,6 +281,9 @@ void ChooseLanguageBox(
|
||||
const auto container = box->verticalLayout();
|
||||
const auto langs = [&] {
|
||||
auto list = TranslationLanguagesList();
|
||||
for (const auto id : list) {
|
||||
LOG(("cloud_lng_language_%1").arg(id.twoLetterCode()));
|
||||
}
|
||||
const auto current = LanguageId{ QLocale(
|
||||
Lang::LanguageIdOrDefault(Lang::Id())).language() };
|
||||
if (const auto i = ranges::find(list, current); i != end(list)) {
|
||||
|
@@ -9,14 +9,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
struct LanguageId;
|
||||
|
||||
namespace tr {
|
||||
struct now_t;
|
||||
} // namespace tr
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class GenericBox;
|
||||
|
||||
[[nodiscard]] QString LanguageNameTranslated(const QString &twoLetterCode);
|
||||
[[nodiscard]] QString LanguageNameLocal(LanguageId id);
|
||||
[[nodiscard]] QString LanguageName(LanguageId id);
|
||||
[[nodiscard]] QString LanguageNameNative(LanguageId id);
|
||||
|
||||
[[nodiscard]] rpl::producer<QString> TranslateBarTo(LanguageId id);
|
||||
[[nodiscard]] QString TranslateMenuDont(tr::now_t, LanguageId id);
|
||||
|
||||
void ChooseLanguageBox(
|
||||
not_null<GenericBox*> box,
|
||||
rpl::producer<QString> title,
|
||||
|
Reference in New Issue
Block a user