Support limited formatting input in factcheck.

This commit is contained in:
John Preston 2024-05-24 11:23:27 +04:00
parent a3ef36f9f7
commit 97a5e0c6ea
16 changed files with 151 additions and 106 deletions

View file

@ -1044,7 +1044,7 @@ not_null<Ui::InputField*> CreatePollBox::setupSolution(
solution->setInstantReplaces(Ui::InstantReplaces::Default()); solution->setInstantReplaces(Ui::InstantReplaces::Default());
solution->setInstantReplacesEnabled( solution->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue()); Core::App().settings().replaceEmojiValue());
solution->setMarkdownReplacesEnabled(rpl::single(true)); solution->setMarkdownReplacesEnabled(true);
solution->setEditLinkCallback( solution->setEditLinkCallback(
DefaultEditLinkCallback(_controller->uiShow(), solution)); DefaultEditLinkCallback(_controller->uiShow(), solution));
solution->customTab(true); solution->customTab(true);

View file

@ -60,60 +60,43 @@ constexpr auto kTypesDuration = 4 * crl::time(1000);
// For mention / custom emoji tags save and validate selfId, // For mention / custom emoji tags save and validate selfId,
// ignore tags for different users. // ignore tags for different users.
class FieldTagMimeProcessor final { [[nodiscard]] Fn<QString(QStringView)> FieldTagMimeProcessor(
public: not_null<Main::Session*> session,
FieldTagMimeProcessor( Fn<bool(not_null<DocumentData*>)> allowPremiumEmoji) {
not_null<Main::Session*> _session, return [=](QStringView mimeTag) {
Fn<bool(not_null<DocumentData*>)> allowPremiumEmoji); const auto id = session->userId().bare;
auto all = TextUtilities::SplitTags(mimeTag);
QString operator()(QStringView mimeTag); auto premiumSkipped = (DocumentData*)nullptr;
for (auto i = all.begin(); i != all.end();) {
private: const auto tag = *i;
const not_null<Main::Session*> _session; if (TextUtilities::IsMentionLink(tag)
const Fn<bool(not_null<DocumentData*>)> _allowPremiumEmoji; && TextUtilities::MentionNameDataToFields(tag).selfId != id) {
};
FieldTagMimeProcessor::FieldTagMimeProcessor(
not_null<Main::Session*> session,
Fn<bool(not_null<DocumentData*>)> allowPremiumEmoji)
: _session(session)
, _allowPremiumEmoji(allowPremiumEmoji) {
}
QString FieldTagMimeProcessor::operator()(QStringView mimeTag) {
const auto id = _session->userId().bare;
auto all = TextUtilities::SplitTags(mimeTag);
auto premiumSkipped = (DocumentData*)nullptr;
for (auto i = all.begin(); i != all.end();) {
const auto tag = *i;
if (TextUtilities::IsMentionLink(tag)
&& TextUtilities::MentionNameDataToFields(tag).selfId != id) {
i = all.erase(i);
continue;
} else if (Ui::InputField::IsCustomEmojiLink(tag)) {
const auto data = Ui::InputField::CustomEmojiEntityData(tag);
const auto emoji = Data::ParseCustomEmojiData(data);
if (!emoji) {
i = all.erase(i); i = all.erase(i);
continue; continue;
} else if (!_session->premium()) { } else if (Ui::InputField::IsCustomEmojiLink(tag)) {
const auto document = _session->data().document(emoji); const auto data = Ui::InputField::CustomEmojiEntityData(tag);
if (document->isPremiumEmoji()) { const auto emoji = Data::ParseCustomEmojiData(data);
if (!_allowPremiumEmoji if (!emoji) {
|| premiumSkipped i = all.erase(i);
|| !_session->premiumPossible() continue;
|| !_allowPremiumEmoji(document)) { } else if (!session->premium()) {
premiumSkipped = document; const auto document = session->data().document(emoji);
i = all.erase(i); if (document->isPremiumEmoji()) {
continue; if (!allowPremiumEmoji
|| premiumSkipped
|| !session->premiumPossible()
|| !allowPremiumEmoji(document)) {
premiumSkipped = document;
i = all.erase(i);
continue;
}
} }
} }
} }
++i;
} }
++i; return TextUtilities::JoinTag(all);
} };
return TextUtilities::JoinTag(all);
} }
//bool ValidateUrl(const QString &value) { //bool ValidateUrl(const QString &value) {
@ -352,7 +335,7 @@ void InitMessageFieldHandlers(
field->setInstantReplaces(Ui::InstantReplaces::Default()); field->setInstantReplaces(Ui::InstantReplaces::Default());
field->setInstantReplacesEnabled( field->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue()); Core::App().settings().replaceEmojiValue());
field->setMarkdownReplacesEnabled(rpl::single(true)); field->setMarkdownReplacesEnabled(true);
if (show) { if (show) {
field->setEditLinkCallback( field->setEditLinkCallback(
DefaultEditLinkCallback(show, field, fieldStyle)); DefaultEditLinkCallback(show, field, fieldStyle));
@ -360,6 +343,42 @@ void InitMessageFieldHandlers(
} }
} }
Fn<void(not_null<Ui::InputField*>)> FactcheckFieldIniter(
std::shared_ptr<Main::SessionShow> show) {
Expects(show != nullptr);
return [=](not_null<Ui::InputField*> field) {
field->setTagMimeProcessor([](QStringView mimeTag) {
using Field = Ui::InputField;
auto all = TextUtilities::SplitTags(mimeTag);
for (auto i = all.begin(); i != all.end();) {
const auto tag = *i;
if (tag != Field::kTagBold
&& tag != Field::kTagItalic
&& (!Field::IsValidMarkdownLink(mimeTag)
|| TextUtilities::IsMentionLink(mimeTag))) {
i = all.erase(i);
continue;
}
++i;
}
return TextUtilities::JoinTag(all);
});
field->setInstantReplaces(Ui::InstantReplaces::Default());
field->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
field->setMarkdownReplacesEnabled(rpl::single(
Ui::MarkdownEnabledState{
Ui::MarkdownEnabled{
{ Ui::InputField::kTagBold, Ui::InputField::kTagItalic }
}
}
));
field->setEditLinkCallback(DefaultEditLinkCallback(show, field));
InitSpellchecker(show, field);
};
}
void InitMessageFieldHandlers( void InitMessageFieldHandlers(
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
not_null<Ui::InputField*> field, not_null<Ui::InputField*> field,

View file

@ -77,6 +77,9 @@ void InitSpellchecker(
not_null<Ui::InputField*> field, not_null<Ui::InputField*> field,
bool skipDictionariesManager = false); bool skipDictionariesManager = false);
[[nodiscard]] Fn<void(not_null<Ui::InputField*>)> FactcheckFieldIniter(
std::shared_ptr<Main::SessionShow> show);
bool HasSendText(not_null<const Ui::InputField*> field); bool HasSendText(not_null<const Ui::InputField*> field);
void InitMessageFieldFade( void InitMessageFieldFade(

View file

@ -199,18 +199,20 @@ void Factchecks::save(
void Factchecks::save( void Factchecks::save(
FullMsgId itemId, FullMsgId itemId,
TextWithEntities was, const TextWithEntities &was,
TextWithEntities text, TextWithEntities text,
std::shared_ptr<Ui::Show> show) { std::shared_ptr<Ui::Show> show) {
const auto done = [=](QString error) { const auto wasEmpty = was.empty();
const auto textEmpty = text.empty();
save(itemId, std::move(text), [=](QString error) {
show->showToast(!error.isEmpty() show->showToast(!error.isEmpty()
? error ? error
: was.empty() : wasEmpty
? tr::lng_factcheck_remove_done(tr::now) ? tr::lng_factcheck_remove_done(tr::now)
: text.empty() : textEmpty
? tr::lng_factcheck_add_done(tr::now) ? tr::lng_factcheck_add_done(tr::now)
: tr::lng_factcheck_edit_done(tr::now)); : tr::lng_factcheck_edit_done(tr::now));
}; });
} }
} // namespace Data } // namespace Data

View file

@ -45,7 +45,7 @@ public:
Fn<void(QString)> done); Fn<void(QString)> done);
void save( void save(
FullMsgId itemId, FullMsgId itemId,
TextWithEntities was, const TextWithEntities &was,
TextWithEntities text, TextWithEntities text,
std::shared_ptr<Ui::Show> show); std::shared_ptr<Ui::Show> show);

View file

@ -2184,7 +2184,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
TextWithEntities result) { TextWithEntities result) {
const auto show = controller->uiShow(); const auto show = controller->uiShow();
session->factchecks().save(itemId, text, result, show); session->factchecks().save(itemId, text, result, show);
})); }, FactcheckFieldIniter(controller->uiShow())));
}, &st::menuIconFactcheck); }, &st::menuIconFactcheck);
} }
const auto pinItem = (item->canPin() && item->isPinned()) const auto pinItem = (item->canPin() && item->isPinned())

View file

@ -69,6 +69,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
#include "data/data_message_reactions.h" #include "data/data_message_reactions.h"
#include "data/stickers/data_custom_emoji.h" #include "data/stickers/data_custom_emoji.h"
#include "chat_helpers/message_field.h" // FactcheckFieldIniter.
#include "core/file_utilities.h" #include "core/file_utilities.h"
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "base/platform/base_platform_info.h" #include "base/platform/base_platform_info.h"
@ -736,7 +737,7 @@ void AddFactcheckAction(
TextWithEntities result) { TextWithEntities result) {
const auto show = controller->uiShow(); const auto show = controller->uiShow();
session->factchecks().save(itemId, text, result, show); session->factchecks().save(itemId, text, result, show);
})); }, FactcheckFieldIniter(controller->uiShow())));
}, &st::menuIconFactcheck); }, &st::menuIconFactcheck);
} }

View file

@ -448,7 +448,7 @@ void MainWindow::updateGlobalMenuHook() {
auto canSelectAll = false; auto canSelectAll = false;
const auto mimeData = QGuiApplication::clipboard()->mimeData(); const auto mimeData = QGuiApplication::clipboard()->mimeData();
const auto clipboardHasText = mimeData ? mimeData->hasText() : false; const auto clipboardHasText = mimeData ? mimeData->hasText() : false;
auto markdownEnabled = false; auto markdownState = Ui::MarkdownEnabledState();
if (const auto edit = qobject_cast<QLineEdit*>(focused)) { if (const auto edit = qobject_cast<QLineEdit*>(focused)) {
canCut = canCopy = canDelete = edit->hasSelectedText(); canCut = canCopy = canDelete = edit->hasSelectedText();
canSelectAll = !edit->text().isEmpty(); canSelectAll = !edit->text().isEmpty();
@ -464,7 +464,7 @@ void MainWindow::updateGlobalMenuHook() {
if (canCopy) { if (canCopy) {
if (const auto inputField = dynamic_cast<Ui::InputField*>( if (const auto inputField = dynamic_cast<Ui::InputField*>(
focused->parentWidget())) { focused->parentWidget())) {
markdownEnabled = inputField->isMarkdownEnabled(); markdownState = inputField->markdownEnabledState();
} }
} }
} else if (const auto list = dynamic_cast<HistoryInner*>(focused)) { } else if (const auto list = dynamic_cast<HistoryInner*>(focused)) {
@ -489,13 +489,19 @@ void MainWindow::updateGlobalMenuHook() {
ForceDisabled(psNewGroup, inactive || support); ForceDisabled(psNewGroup, inactive || support);
ForceDisabled(psNewChannel, inactive || support); ForceDisabled(psNewChannel, inactive || support);
ForceDisabled(psBold, !markdownEnabled); const auto diabled = [=](const QString &tag) {
ForceDisabled(psItalic, !markdownEnabled); return !markdownState.enabledForTag(tag);
ForceDisabled(psUnderline, !markdownEnabled); };
ForceDisabled(psStrikeOut, !markdownEnabled); using Field = Ui::InputField;
ForceDisabled(psBlockquote, !markdownEnabled); ForceDisabled(psBold, diabled(Field::kTagBold));
ForceDisabled(psMonospace, !markdownEnabled); ForceDisabled(psItalic, diabled(Field::kTagItalic));
ForceDisabled(psClearFormat, !markdownEnabled); ForceDisabled(psUnderline, diabled(Field::kTagUnderline));
ForceDisabled(psStrikeOut, diabled(Field::kTagStrikeOut));
ForceDisabled(psBlockquote, diabled(Field::kTagBlockquote));
ForceDisabled(
psMonospace,
diabled(Field::kTagPre) || diabled(Field::kTagCode));
ForceDisabled(psClearFormat, markdownState.disabled());
} }
bool MainWindow::eventFilter(QObject *obj, QEvent *evt) { bool MainWindow::eventFilter(QObject *obj, QEvent *evt) {

View file

@ -64,8 +64,6 @@ private:
base::Timer _hideAfterFullScreenTimer; base::Timer _hideAfterFullScreenTimer;
rpl::variable<bool> _canApplyMarkdown;
QMenuBar psMainMenu; QMenuBar psMainMenu;
QAction *psLogout = nullptr; QAction *psLogout = nullptr;
QAction *psUndo = nullptr; QAction *psUndo = nullptr;

View file

@ -92,10 +92,11 @@ public:
void setNativeWindow(NSWindow *window, NSView *view); void setNativeWindow(NSWindow *window, NSView *view);
void initTouchBar( void initTouchBar(
NSWindow *window, NSWindow *window,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller);
rpl::producer<bool> canApplyMarkdown);
void setWindowBadge(const QString &str); void setWindowBadge(const QString &str);
void setMarkdownEnabledState(Ui::MarkdownEnabledState state);
bool clipboardHasText(); bool clipboardHasText();
~Private(); ~Private();
@ -103,6 +104,8 @@ private:
not_null<MainWindow*> _public; not_null<MainWindow*> _public;
friend class MainWindow; friend class MainWindow;
rpl::variable<Ui::MarkdownEnabledState> _markdownState;
NSWindow * __weak _nativeWindow = nil; NSWindow * __weak _nativeWindow = nil;
NSView * __weak _nativeView = nil; NSView * __weak _nativeView = nil;
@ -229,8 +232,7 @@ void MainWindow::Private::setNativeWindow(NSWindow *window, NSView *view) {
void MainWindow::Private::initTouchBar( void MainWindow::Private::initTouchBar(
NSWindow *window, NSWindow *window,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller) {
rpl::producer<bool> canApplyMarkdown) {
if (!IsMac10_13OrGreater()) { if (!IsMac10_13OrGreater()) {
return; return;
} }
@ -240,12 +242,17 @@ void MainWindow::Private::initTouchBar(
[window [window
performSelectorOnMainThread:@selector(setTouchBar:) performSelectorOnMainThread:@selector(setTouchBar:)
withObject:[[[RootTouchBar alloc] withObject:[[[RootTouchBar alloc]
init:std::move(canApplyMarkdown) init:_markdownState.value()
controller:controller controller:controller
domain:(&Core::App().domain())] autorelease] domain:(&Core::App().domain())] autorelease]
waitUntilDone:true]; waitUntilDone:true];
} }
void MainWindow::Private::setMarkdownEnabledState(
Ui::MarkdownEnabledState state) {
_markdownState = state;
}
bool MainWindow::Private::clipboardHasText() { bool MainWindow::Private::clipboardHasText() {
auto currentChangeCount = static_cast<int>([_generalPasteboard changeCount]); auto currentChangeCount = static_cast<int>([_generalPasteboard changeCount]);
if (_generalPasteboardChangeCount != currentChangeCount) { if (_generalPasteboardChangeCount != currentChangeCount) {
@ -289,10 +296,7 @@ void MainWindow::initHook() {
if (auto view = reinterpret_cast<NSView*>(winId())) { if (auto view = reinterpret_cast<NSView*>(winId())) {
if (auto window = [view window]) { if (auto window = [view window]) {
_private->setNativeWindow(window, view); _private->setNativeWindow(window, view);
_private->initTouchBar( _private->initTouchBar(window, &controller());
window,
&controller(),
_canApplyMarkdown.changes());
} }
} }
} }
@ -558,7 +562,7 @@ void MainWindow::updateGlobalMenuHook() {
auto focused = QApplication::focusWidget(); auto focused = QApplication::focusWidget();
bool canUndo = false, canRedo = false, canCut = false, canCopy = false, canPaste = false, canDelete = false, canSelectAll = false; bool canUndo = false, canRedo = false, canCut = false, canCopy = false, canPaste = false, canDelete = false, canSelectAll = false;
auto clipboardHasText = _private->clipboardHasText(); auto clipboardHasText = _private->clipboardHasText();
auto canApplyMarkdown = false; auto markdownState = Ui::MarkdownEnabledState();
if (auto edit = qobject_cast<QLineEdit*>(focused)) { if (auto edit = qobject_cast<QLineEdit*>(focused)) {
canCut = canCopy = canDelete = edit->hasSelectedText(); canCut = canCopy = canDelete = edit->hasSelectedText();
canSelectAll = !edit->text().isEmpty(); canSelectAll = !edit->text().isEmpty();
@ -574,7 +578,7 @@ void MainWindow::updateGlobalMenuHook() {
if (canCopy) { if (canCopy) {
if (const auto inputField = dynamic_cast<Ui::InputField*>( if (const auto inputField = dynamic_cast<Ui::InputField*>(
focused->parentWidget())) { focused->parentWidget())) {
canApplyMarkdown = inputField->isMarkdownEnabled(); markdownState = inputField->markdownEnabledState();
} }
} }
} else if (auto list = dynamic_cast<HistoryInner*>(focused)) { } else if (auto list = dynamic_cast<HistoryInner*>(focused)) {
@ -582,7 +586,7 @@ void MainWindow::updateGlobalMenuHook() {
canDelete = list->canDeleteSelected(); canDelete = list->canDeleteSelected();
} }
_canApplyMarkdown = canApplyMarkdown; _private->setMarkdownEnabledState(markdownState);
updateIsActive(); updateIsActive();
const auto logged = (sessionController() != nullptr); const auto logged = (sessionController() != nullptr);
@ -603,13 +607,19 @@ void MainWindow::updateGlobalMenuHook() {
ForceDisabled(psNewChannel, inactive || support); ForceDisabled(psNewChannel, inactive || support);
ForceDisabled(psShowTelegram, isActive()); ForceDisabled(psShowTelegram, isActive());
ForceDisabled(psBold, !canApplyMarkdown); const auto diabled = [=](const QString &tag) {
ForceDisabled(psItalic, !canApplyMarkdown); return !markdownState.enabledForTag(tag);
ForceDisabled(psUnderline, !canApplyMarkdown); };
ForceDisabled(psStrikeOut, !canApplyMarkdown); using Field = Ui::InputField;
ForceDisabled(psBlockquote, !canApplyMarkdown); ForceDisabled(psBold, diabled(Field::kTagBold));
ForceDisabled(psMonospace, !canApplyMarkdown); ForceDisabled(psItalic, diabled(Field::kTagItalic));
ForceDisabled(psClearFormat, !canApplyMarkdown); ForceDisabled(psUnderline, diabled(Field::kTagUnderline));
ForceDisabled(psStrikeOut, diabled(Field::kTagStrikeOut));
ForceDisabled(psBlockquote, diabled(Field::kTagBlockquote));
ForceDisabled(
psMonospace,
diabled(Field::kTagPre) || diabled(Field::kTagCode));
ForceDisabled(psClearFormat, markdownState.disabled());
} }
bool MainWindow::eventFilter(QObject *obj, QEvent *evt) { bool MainWindow::eventFilter(QObject *obj, QEvent *evt) {

View file

@ -17,9 +17,13 @@ namespace Window {
class Controller; class Controller;
} // namespace Window } // namespace Window
namespace Ui {
struct MarkdownEnabledState;
} // namespace Ui
API_AVAILABLE(macos(10.12.2)) API_AVAILABLE(macos(10.12.2))
@interface RootTouchBar : NSTouchBar<NSTouchBarDelegate> @interface RootTouchBar : NSTouchBar<NSTouchBarDelegate>
- (id)init:(rpl::producer<bool>)canApplyMarkdown - (id)init:(rpl::producer<Ui::MarkdownEnabledState>)markdownState
controller:(not_null<Window::Controller*>)controller controller:(not_null<Window::Controller*>)controller
domain:(not_null<Main::Domain*>)domain; domain:(not_null<Main::Domain*>)domain;
@end @end

View file

@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/mac/touchbar/mac_touchbar_audio.h" #include "platform/mac/touchbar/mac_touchbar_audio.h"
#include "platform/mac/touchbar/mac_touchbar_common.h" #include "platform/mac/touchbar/mac_touchbar_common.h"
#include "platform/mac/touchbar/mac_touchbar_main.h" #include "platform/mac/touchbar/mac_touchbar_main.h"
#include "ui/widgets/fields/input_field.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
@ -57,13 +58,12 @@ const auto kAudioItemIdentifier = @"touchbarAudio";
Main::Session *_session; Main::Session *_session;
Window::Controller *_controller; Window::Controller *_controller;
bool _canApplyMarkdownLast; rpl::variable<Ui::MarkdownEnabledState> _markdownState;
rpl::event_stream<bool> _canApplyMarkdown;
rpl::event_stream<> _touchBarSwitches; rpl::event_stream<> _touchBarSwitches;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;
} }
- (id)init:(rpl::producer<bool>)canApplyMarkdown - (id)init:(rpl::producer<Ui::MarkdownEnabledState>)markdownState
controller:(not_null<Window::Controller*>)controller controller:(not_null<Window::Controller*>)controller
domain:(not_null<Main::Domain*>)domain { domain:(not_null<Main::Domain*>)domain {
self = [super init]; self = [super init];
@ -75,10 +75,7 @@ const auto kAudioItemIdentifier = @"touchbarAudio";
self.defaultItemIdentifiers = @[]; self.defaultItemIdentifiers = @[];
}); });
_controller = controller; _controller = controller;
_canApplyMarkdownLast = false; _markdownState = std::move(markdownState);
std::move(
canApplyMarkdown
) | rpl::start_to_stream(_canApplyMarkdown, _lifetime);
auto sessionChanges = domain->activeSessionChanges( auto sessionChanges = domain->activeSessionChanges(
) | rpl::map([=](Main::Session *session) { ) | rpl::map([=](Main::Session *session) {
@ -140,8 +137,7 @@ const auto kAudioItemIdentifier = @"touchbarAudio";
init:_controller init:_controller
touchBarSwitches:_touchBarSwitches.events()] autorelease]; touchBarSwitches:_touchBarSwitches.events()] autorelease];
rpl::combine( rpl::combine(
_canApplyMarkdown.events_starting_with_copy( _markdownState.value(),
_canApplyMarkdownLast),
_controller->sessionController()->activeChatValue( _controller->sessionController()->activeChatValue(
) | rpl::map([](Dialogs::Key k) { ) | rpl::map([](Dialogs::Key k) {
const auto topic = k.topic(); const auto topic = k.topic();
@ -153,16 +149,15 @@ const auto kAudioItemIdentifier = @"touchbarAudio";
: (peer && Data::CanSendAnyOf(peer, rights)); : (peer && Data::CanSendAnyOf(peer, rights));
}) | rpl::distinct_until_changed() }) | rpl::distinct_until_changed()
) | rpl::start_with_next([=]( ) | rpl::start_with_next([=](
bool canApplyMarkdown, Ui::MarkdownEnabledState state,
bool hasActiveChat) { bool hasActiveChat) {
_canApplyMarkdownLast = canApplyMarkdown;
item.groupTouchBar.defaultItemIdentifiers = @[ item.groupTouchBar.defaultItemIdentifiers = @[
kPinnedPanelItemIdentifier, kPinnedPanelItemIdentifier,
canApplyMarkdown (!state.disabled()
? kPopoverInputItemIdentifier ? kPopoverInputItemIdentifier
: hasActiveChat : hasActiveChat
? kPopoverPickerItemIdentifier ? kPopoverPickerItemIdentifier
: @""]; : @"")];
}, [item lifetime]); }, [item lifetime]);
return [item autorelease]; return [item autorelease];

View file

@ -88,7 +88,7 @@ EditInfoBox::EditInfoBox(
_field->setInstantReplaces(Ui::InstantReplaces::Default()); _field->setInstantReplaces(Ui::InstantReplaces::Default());
_field->setInstantReplacesEnabled( _field->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue()); Core::App().settings().replaceEmojiValue());
_field->setMarkdownReplacesEnabled(rpl::single(true)); _field->setMarkdownReplacesEnabled(true);
_field->setEditLinkCallback( _field->setEditLinkCallback(
DefaultEditLinkCallback(controller->uiShow(), _field)); DefaultEditLinkCallback(controller->uiShow(), _field));
} }

View file

@ -16,7 +16,8 @@ void EditFactcheckBox(
not_null<Ui::GenericBox*> box, not_null<Ui::GenericBox*> box,
TextWithEntities current, TextWithEntities current,
int limit, int limit,
Fn<void(TextWithEntities)> save) { Fn<void(TextWithEntities)> save,
Fn<void(not_null<Ui::InputField*>)> initField) {
box->setTitle(tr::lng_factcheck_title()); box->setTitle(tr::lng_factcheck_title());
const auto field = box->addRow(object_ptr<Ui::InputField>( const auto field = box->addRow(object_ptr<Ui::InputField>(
@ -29,6 +30,7 @@ void EditFactcheckBox(
TextUtilities::ConvertEntitiesToTextTags(current.entities) TextUtilities::ConvertEntitiesToTextTags(current.entities)
})); }));
AddLengthLimitLabel(field, limit); AddLengthLimitLabel(field, limit);
initField(field);
enum class State { enum class State {
Initial, Initial,

View file

@ -9,8 +9,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/layers/generic_box.h" #include "ui/layers/generic_box.h"
namespace Ui {
class InputField;
} // namespace Ui
void EditFactcheckBox( void EditFactcheckBox(
not_null<Ui::GenericBox*> box, not_null<Ui::GenericBox*> box,
TextWithEntities current, TextWithEntities current,
int limit, int limit,
Fn<void(TextWithEntities)> save); Fn<void(TextWithEntities)> save,
Fn<void(not_null<Ui::InputField*>)> initField);

@ -1 +1 @@
Subproject commit e7c598affe724322577ef46d9a07d1dcac3c617b Subproject commit 0835adcc2d3cb1f2cf0d3630f6d95485864621f9