Allow editing syntax highlighting language.

This commit is contained in:
John Preston 2024-06-10 18:05:37 +04:00
parent fa8ed186d8
commit 5e8c3fb146
6 changed files with 86 additions and 11 deletions

View file

@ -3582,6 +3582,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_formatting_link_text" = "Text";
"lng_formatting_link_url" = "URL";
"lng_formatting_link_create" = "Create";
"lng_formatting_code_title" = "Code Language";
"lng_formatting_code_language" = "Language for syntax highlighting.";
"lng_formatting_code_auto" = "Auto-Detect";
"lng_text_copied" = "Text copied to clipboard.";
"lng_code_copied" = "Block copied to clipboard.";

View file

@ -1044,7 +1044,16 @@ not_null<Ui::InputField*> CreatePollBox::setupSolution(
solution->setInstantReplaces(Ui::InstantReplaces::Default());
solution->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
solution->setMarkdownReplacesEnabled(true);
solution->setMarkdownReplacesEnabled(rpl::single(
Ui::MarkdownEnabledState{ Ui::MarkdownEnabled{ {
Ui::InputField::kTagBold,
Ui::InputField::kTagItalic,
Ui::InputField::kTagUnderline,
Ui::InputField::kTagStrikeOut,
Ui::InputField::kTagCode,
Ui::InputField::kTagSpoiler,
} } }
));
solution->setEditLinkCallback(
DefaultEditLinkCallback(_controller->uiShow(), solution));
solution->customTab(true);

View file

@ -41,6 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_boxes.h"
#include "styles/style_chat.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_settings.h"
#include "base/qt/qt_common_adapters.h"
#include <QtCore/QMimeData>
@ -59,6 +60,7 @@ using EditLinkSelection = Ui::InputField::EditLinkSelection;
constexpr auto kParseLinksTimeout = crl::time(1000);
constexpr auto kTypesDuration = 4 * crl::time(1000);
constexpr auto kCodeLanguageLimit = 32;
// For mention / custom emoji tags save and validate selfId,
// ignore tags for different users.
@ -223,6 +225,51 @@ void EditLinkBox(
}, text->lifetime());
}
void EditCodeLanguageBox(
not_null<Ui::GenericBox*> box,
QString now,
Fn<void(QString)> save) {
Expects(save != nullptr);
box->setTitle(tr::lng_formatting_code_title());
box->addRow(object_ptr<Ui::FlatLabel>(
box,
tr::lng_formatting_code_language(),
st::settingsAddReplyLabel));
const auto field = box->addRow(object_ptr<Ui::InputField>(
box,
st::settingsAddReplyField,
tr::lng_formatting_code_auto(),
now.trimmed()));
box->setFocusCallback([=] {
field->setFocusFast();
});
field->selectAll();
field->setMaxLength(kCodeLanguageLimit);
Ui::AddLengthLimitLabel(field, kCodeLanguageLimit);
const auto callback = [=] {
const auto name = field->getLastText().trimmed();
const auto check = QRegularExpression("^[a-zA-Z0-9\\+\\-]+$");
if (check.match(name).hasMatch()) {
auto weak = Ui::MakeWeak(box);
save(name);
if (const auto strong = weak.data()) {
strong->closeBox();
}
} else {
field->showError();
}
};
field->submits(
) | rpl::start_with_next(callback, field->lifetime());
box->addButton(tr::lng_settings_save(), callback);
box->addButton(tr::lng_cancel(), [=] {
box->closeBox();
});
}
TextWithEntities StripSupportHashtag(TextWithEntities text) {
static const auto expression = QRegularExpression(
u"\\n?#tsf[a-z0-9_-]*[\\s#a-z0-9_-]*$"_q,
@ -321,6 +368,13 @@ Fn<bool(
};
}
Fn<void(QString now, Fn<void(QString)> save)> DefaultEditLanguageCallback(
std::shared_ptr<Ui::Show> show) {
return [=](QString now, Fn<void(QString)> save) {
show->showBox(Box(EditCodeLanguageBox, now, save));
};
}
void InitMessageFieldHandlers(
not_null<Main::Session*> session,
std::shared_ptr<Main::SessionShow> show,
@ -343,6 +397,7 @@ void InitMessageFieldHandlers(
if (show) {
field->setEditLinkCallback(
DefaultEditLinkCallback(show, field, fieldStyle));
field->setEditLanguageCallback(DefaultEditLanguageCallback(show));
InitSpellchecker(show, field, fieldStyle != nullptr);
}
const auto style = field->lifetime().make_state<Ui::ChatStyle>(
@ -585,15 +640,19 @@ void InitMessageFieldFade(
field->scrollTop().changes() | rpl::to_empty,
field->sizeValue() | rpl::to_empty
) | rpl::start_with_next([=] {
const auto topHidden = !field->scrollTop().current();
if (topFade->isHidden() != topHidden) {
topFade->setVisible(!topHidden);
}
const auto adjusted = field->scrollTop().current() + descent;
const auto bottomHidden = (adjusted >= field->scrollTopMax());
if (bottomFade->isHidden() != bottomHidden) {
bottomFade->setVisible(!bottomHidden);
}
// InputField::changes fires before the auto-resize is being applied,
// so for the scroll values to be accurate we enqueue the check.
InvokeQueued(field, [=] {
const auto topHidden = !field->scrollTop().current();
if (topFade->isHidden() != topHidden) {
topFade->setVisible(!topHidden);
}
const auto adjusted = field->scrollTop().current() + descent;
const auto bottomHidden = (adjusted >= field->scrollTopMax());
if (bottomFade->isHidden() != bottomHidden) {
bottomFade->setVisible(!bottomHidden);
}
});
}, topFade->lifetime());
}

View file

@ -35,6 +35,7 @@ class Show;
namespace Ui {
class PopupMenu;
class Show;
} // namespace Ui
[[nodiscard]] QString PrepareMentionTag(not_null<UserData*> user);
@ -51,6 +52,8 @@ Fn<bool(
std::shared_ptr<Main::SessionShow> show,
not_null<Ui::InputField*> field,
const style::InputField *fieldStyle = nullptr);
Fn<void(QString now, Fn<void(QString)> save)> DefaultEditLanguageCallback(
std::shared_ptr<Ui::Show> show);
void InitMessageFieldHandlers(
not_null<Main::Session*> session,
std::shared_ptr<Main::SessionShow> show, // may be null

View file

@ -1658,6 +1658,7 @@ void ComposeControls::initField() {
InitMessageFieldFade(_field, _st.field.textBg);
_field->setEditLinkCallback(
DefaultEditLinkCallback(_show, _field, &_st.boxField));
_field->setEditLanguageCallback(DefaultEditLanguageCallback(_show));
initAutocomplete();
const auto allow = [=](not_null<DocumentData*> emoji) {
return _history

@ -1 +1 @@
Subproject commit d4d51136cd5ff54b84b2863a7ece39693b5ce522
Subproject commit 20caa93a8d2b5b279f36eb19d9200be071420ba3