From 97a5e0c6ea3a0b06005ee3bf1bdaeaf174ed4406 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 24 May 2024 11:23:27 +0400 Subject: [PATCH] Support limited formatting input in factcheck. --- .../SourceFiles/boxes/create_poll_box.cpp | 2 +- .../chat_helpers/message_field.cpp | 117 ++++++++++-------- .../SourceFiles/chat_helpers/message_field.h | 3 + .../data/components/factchecks.cpp | 12 +- .../SourceFiles/data/components/factchecks.h | 2 +- .../history/history_inner_widget.cpp | 2 +- .../view/history_view_context_menu.cpp | 3 +- .../platform/linux/main_window_linux.cpp | 24 ++-- .../platform/mac/main_window_mac.h | 2 - .../platform/mac/main_window_mac.mm | 48 ++++--- .../mac/touchbar/mac_touchbar_manager.h | 6 +- .../mac/touchbar/mac_touchbar_manager.mm | 21 ++-- .../SourceFiles/support/support_helper.cpp | 2 +- .../ui/boxes/edit_factcheck_box.cpp | 4 +- .../SourceFiles/ui/boxes/edit_factcheck_box.h | 7 +- Telegram/lib_ui | 2 +- 16 files changed, 151 insertions(+), 106 deletions(-) diff --git a/Telegram/SourceFiles/boxes/create_poll_box.cpp b/Telegram/SourceFiles/boxes/create_poll_box.cpp index 151ab54b8..46138e3fd 100644 --- a/Telegram/SourceFiles/boxes/create_poll_box.cpp +++ b/Telegram/SourceFiles/boxes/create_poll_box.cpp @@ -1044,7 +1044,7 @@ not_null CreatePollBox::setupSolution( solution->setInstantReplaces(Ui::InstantReplaces::Default()); solution->setInstantReplacesEnabled( Core::App().settings().replaceEmojiValue()); - solution->setMarkdownReplacesEnabled(rpl::single(true)); + solution->setMarkdownReplacesEnabled(true); solution->setEditLinkCallback( DefaultEditLinkCallback(_controller->uiShow(), solution)); solution->customTab(true); diff --git a/Telegram/SourceFiles/chat_helpers/message_field.cpp b/Telegram/SourceFiles/chat_helpers/message_field.cpp index 557d0c337..836459ad8 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.cpp +++ b/Telegram/SourceFiles/chat_helpers/message_field.cpp @@ -60,60 +60,43 @@ constexpr auto kTypesDuration = 4 * crl::time(1000); // For mention / custom emoji tags save and validate selfId, // ignore tags for different users. -class FieldTagMimeProcessor final { -public: - FieldTagMimeProcessor( - not_null _session, - Fn)> allowPremiumEmoji); - - QString operator()(QStringView mimeTag); - -private: - const not_null _session; - const Fn)> _allowPremiumEmoji; - -}; - -FieldTagMimeProcessor::FieldTagMimeProcessor( - not_null session, - Fn)> 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) { +[[nodiscard]] Fn FieldTagMimeProcessor( + not_null session, + Fn)> allowPremiumEmoji) { + return [=](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 (!_session->premium()) { - const auto document = _session->data().document(emoji); - if (document->isPremiumEmoji()) { - if (!_allowPremiumEmoji - || premiumSkipped - || !_session->premiumPossible() - || !_allowPremiumEmoji(document)) { - premiumSkipped = document; - 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); + continue; + } else if (!session->premium()) { + const auto document = session->data().document(emoji); + if (document->isPremiumEmoji()) { + 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) { @@ -352,7 +335,7 @@ void InitMessageFieldHandlers( field->setInstantReplaces(Ui::InstantReplaces::Default()); field->setInstantReplacesEnabled( Core::App().settings().replaceEmojiValue()); - field->setMarkdownReplacesEnabled(rpl::single(true)); + field->setMarkdownReplacesEnabled(true); if (show) { field->setEditLinkCallback( DefaultEditLinkCallback(show, field, fieldStyle)); @@ -360,6 +343,42 @@ void InitMessageFieldHandlers( } } +Fn)> FactcheckFieldIniter( + std::shared_ptr show) { + Expects(show != nullptr); + + return [=](not_null 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( not_null controller, not_null field, diff --git a/Telegram/SourceFiles/chat_helpers/message_field.h b/Telegram/SourceFiles/chat_helpers/message_field.h index 0c9d8ff85..1e67642a7 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.h +++ b/Telegram/SourceFiles/chat_helpers/message_field.h @@ -77,6 +77,9 @@ void InitSpellchecker( not_null field, bool skipDictionariesManager = false); +[[nodiscard]] Fn)> FactcheckFieldIniter( + std::shared_ptr show); + bool HasSendText(not_null field); void InitMessageFieldFade( diff --git a/Telegram/SourceFiles/data/components/factchecks.cpp b/Telegram/SourceFiles/data/components/factchecks.cpp index 07051dabd..d068f8146 100644 --- a/Telegram/SourceFiles/data/components/factchecks.cpp +++ b/Telegram/SourceFiles/data/components/factchecks.cpp @@ -199,18 +199,20 @@ void Factchecks::save( void Factchecks::save( FullMsgId itemId, - TextWithEntities was, + const TextWithEntities &was, TextWithEntities text, std::shared_ptr 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() ? error - : was.empty() + : wasEmpty ? tr::lng_factcheck_remove_done(tr::now) - : text.empty() + : textEmpty ? tr::lng_factcheck_add_done(tr::now) : tr::lng_factcheck_edit_done(tr::now)); - }; + }); } } // namespace Data diff --git a/Telegram/SourceFiles/data/components/factchecks.h b/Telegram/SourceFiles/data/components/factchecks.h index 515e52286..a7eaca3d4 100644 --- a/Telegram/SourceFiles/data/components/factchecks.h +++ b/Telegram/SourceFiles/data/components/factchecks.h @@ -45,7 +45,7 @@ public: Fn done); void save( FullMsgId itemId, - TextWithEntities was, + const TextWithEntities &was, TextWithEntities text, std::shared_ptr show); diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 76fa5c463..57f11e678 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -2184,7 +2184,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { TextWithEntities result) { const auto show = controller->uiShow(); session->factchecks().save(itemId, text, result, show); - })); + }, FactcheckFieldIniter(controller->uiShow()))); }, &st::menuIconFactcheck); } const auto pinItem = (item->canPin() && item->isPinned()) diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index 3d47b358e..b217777a5 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -69,6 +69,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_file_origin.h" #include "data/data_message_reactions.h" #include "data/stickers/data_custom_emoji.h" +#include "chat_helpers/message_field.h" // FactcheckFieldIniter. #include "core/file_utilities.h" #include "core/click_handler_types.h" #include "base/platform/base_platform_info.h" @@ -736,7 +737,7 @@ void AddFactcheckAction( TextWithEntities result) { const auto show = controller->uiShow(); session->factchecks().save(itemId, text, result, show); - })); + }, FactcheckFieldIniter(controller->uiShow()))); }, &st::menuIconFactcheck); } diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index ba73e3b3a..ff9fddc74 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -448,7 +448,7 @@ void MainWindow::updateGlobalMenuHook() { auto canSelectAll = false; const auto mimeData = QGuiApplication::clipboard()->mimeData(); const auto clipboardHasText = mimeData ? mimeData->hasText() : false; - auto markdownEnabled = false; + auto markdownState = Ui::MarkdownEnabledState(); if (const auto edit = qobject_cast(focused)) { canCut = canCopy = canDelete = edit->hasSelectedText(); canSelectAll = !edit->text().isEmpty(); @@ -464,7 +464,7 @@ void MainWindow::updateGlobalMenuHook() { if (canCopy) { if (const auto inputField = dynamic_cast( focused->parentWidget())) { - markdownEnabled = inputField->isMarkdownEnabled(); + markdownState = inputField->markdownEnabledState(); } } } else if (const auto list = dynamic_cast(focused)) { @@ -489,13 +489,19 @@ void MainWindow::updateGlobalMenuHook() { ForceDisabled(psNewGroup, inactive || support); ForceDisabled(psNewChannel, inactive || support); - ForceDisabled(psBold, !markdownEnabled); - ForceDisabled(psItalic, !markdownEnabled); - ForceDisabled(psUnderline, !markdownEnabled); - ForceDisabled(psStrikeOut, !markdownEnabled); - ForceDisabled(psBlockquote, !markdownEnabled); - ForceDisabled(psMonospace, !markdownEnabled); - ForceDisabled(psClearFormat, !markdownEnabled); + const auto diabled = [=](const QString &tag) { + return !markdownState.enabledForTag(tag); + }; + using Field = Ui::InputField; + ForceDisabled(psBold, diabled(Field::kTagBold)); + ForceDisabled(psItalic, diabled(Field::kTagItalic)); + 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) { diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.h b/Telegram/SourceFiles/platform/mac/main_window_mac.h index 2a3a59b9c..63ed4009b 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.h +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.h @@ -64,8 +64,6 @@ private: base::Timer _hideAfterFullScreenTimer; - rpl::variable _canApplyMarkdown; - QMenuBar psMainMenu; QAction *psLogout = nullptr; QAction *psUndo = nullptr; diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 9b0dd14bb..43ba894b4 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -92,10 +92,11 @@ public: void setNativeWindow(NSWindow *window, NSView *view); void initTouchBar( NSWindow *window, - not_null controller, - rpl::producer canApplyMarkdown); + not_null controller); void setWindowBadge(const QString &str); + void setMarkdownEnabledState(Ui::MarkdownEnabledState state); + bool clipboardHasText(); ~Private(); @@ -103,6 +104,8 @@ private: not_null _public; friend class MainWindow; + rpl::variable _markdownState; + NSWindow * __weak _nativeWindow = nil; NSView * __weak _nativeView = nil; @@ -229,8 +232,7 @@ void MainWindow::Private::setNativeWindow(NSWindow *window, NSView *view) { void MainWindow::Private::initTouchBar( NSWindow *window, - not_null controller, - rpl::producer canApplyMarkdown) { + not_null controller) { if (!IsMac10_13OrGreater()) { return; } @@ -240,12 +242,17 @@ void MainWindow::Private::initTouchBar( [window performSelectorOnMainThread:@selector(setTouchBar:) withObject:[[[RootTouchBar alloc] - init:std::move(canApplyMarkdown) + init:_markdownState.value() controller:controller domain:(&Core::App().domain())] autorelease] waitUntilDone:true]; } +void MainWindow::Private::setMarkdownEnabledState( + Ui::MarkdownEnabledState state) { + _markdownState = state; +} + bool MainWindow::Private::clipboardHasText() { auto currentChangeCount = static_cast([_generalPasteboard changeCount]); if (_generalPasteboardChangeCount != currentChangeCount) { @@ -289,10 +296,7 @@ void MainWindow::initHook() { if (auto view = reinterpret_cast(winId())) { if (auto window = [view window]) { _private->setNativeWindow(window, view); - _private->initTouchBar( - window, - &controller(), - _canApplyMarkdown.changes()); + _private->initTouchBar(window, &controller()); } } } @@ -558,7 +562,7 @@ void MainWindow::updateGlobalMenuHook() { auto focused = QApplication::focusWidget(); bool canUndo = false, canRedo = false, canCut = false, canCopy = false, canPaste = false, canDelete = false, canSelectAll = false; auto clipboardHasText = _private->clipboardHasText(); - auto canApplyMarkdown = false; + auto markdownState = Ui::MarkdownEnabledState(); if (auto edit = qobject_cast(focused)) { canCut = canCopy = canDelete = edit->hasSelectedText(); canSelectAll = !edit->text().isEmpty(); @@ -574,7 +578,7 @@ void MainWindow::updateGlobalMenuHook() { if (canCopy) { if (const auto inputField = dynamic_cast( focused->parentWidget())) { - canApplyMarkdown = inputField->isMarkdownEnabled(); + markdownState = inputField->markdownEnabledState(); } } } else if (auto list = dynamic_cast(focused)) { @@ -582,7 +586,7 @@ void MainWindow::updateGlobalMenuHook() { canDelete = list->canDeleteSelected(); } - _canApplyMarkdown = canApplyMarkdown; + _private->setMarkdownEnabledState(markdownState); updateIsActive(); const auto logged = (sessionController() != nullptr); @@ -603,13 +607,19 @@ void MainWindow::updateGlobalMenuHook() { ForceDisabled(psNewChannel, inactive || support); ForceDisabled(psShowTelegram, isActive()); - ForceDisabled(psBold, !canApplyMarkdown); - ForceDisabled(psItalic, !canApplyMarkdown); - ForceDisabled(psUnderline, !canApplyMarkdown); - ForceDisabled(psStrikeOut, !canApplyMarkdown); - ForceDisabled(psBlockquote, !canApplyMarkdown); - ForceDisabled(psMonospace, !canApplyMarkdown); - ForceDisabled(psClearFormat, !canApplyMarkdown); + const auto diabled = [=](const QString &tag) { + return !markdownState.enabledForTag(tag); + }; + using Field = Ui::InputField; + ForceDisabled(psBold, diabled(Field::kTagBold)); + ForceDisabled(psItalic, diabled(Field::kTagItalic)); + 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) { diff --git a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.h b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.h index 464f87c9c..f34cf8190 100644 --- a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.h +++ b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.h @@ -17,9 +17,13 @@ namespace Window { class Controller; } // namespace Window +namespace Ui { +struct MarkdownEnabledState; +} // namespace Ui + API_AVAILABLE(macos(10.12.2)) @interface RootTouchBar : NSTouchBar -- (id)init:(rpl::producer)canApplyMarkdown +- (id)init:(rpl::producer)markdownState controller:(not_null)controller domain:(not_null)domain; @end diff --git a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.mm b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.mm index 5f314e4b5..ea273dab7 100644 --- a/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.mm +++ b/Telegram/SourceFiles/platform/mac/touchbar/mac_touchbar_manager.mm @@ -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_common.h" #include "platform/mac/touchbar/mac_touchbar_main.h" +#include "ui/widgets/fields/input_field.h" #include "window/window_controller.h" #include "window/window_session_controller.h" @@ -57,13 +58,12 @@ const auto kAudioItemIdentifier = @"touchbarAudio"; Main::Session *_session; Window::Controller *_controller; - bool _canApplyMarkdownLast; - rpl::event_stream _canApplyMarkdown; + rpl::variable _markdownState; rpl::event_stream<> _touchBarSwitches; rpl::lifetime _lifetime; } -- (id)init:(rpl::producer)canApplyMarkdown +- (id)init:(rpl::producer)markdownState controller:(not_null)controller domain:(not_null)domain { self = [super init]; @@ -75,10 +75,7 @@ const auto kAudioItemIdentifier = @"touchbarAudio"; self.defaultItemIdentifiers = @[]; }); _controller = controller; - _canApplyMarkdownLast = false; - std::move( - canApplyMarkdown - ) | rpl::start_to_stream(_canApplyMarkdown, _lifetime); + _markdownState = std::move(markdownState); auto sessionChanges = domain->activeSessionChanges( ) | rpl::map([=](Main::Session *session) { @@ -140,8 +137,7 @@ const auto kAudioItemIdentifier = @"touchbarAudio"; init:_controller touchBarSwitches:_touchBarSwitches.events()] autorelease]; rpl::combine( - _canApplyMarkdown.events_starting_with_copy( - _canApplyMarkdownLast), + _markdownState.value(), _controller->sessionController()->activeChatValue( ) | rpl::map([](Dialogs::Key k) { const auto topic = k.topic(); @@ -153,16 +149,15 @@ const auto kAudioItemIdentifier = @"touchbarAudio"; : (peer && Data::CanSendAnyOf(peer, rights)); }) | rpl::distinct_until_changed() ) | rpl::start_with_next([=]( - bool canApplyMarkdown, + Ui::MarkdownEnabledState state, bool hasActiveChat) { - _canApplyMarkdownLast = canApplyMarkdown; item.groupTouchBar.defaultItemIdentifiers = @[ kPinnedPanelItemIdentifier, - canApplyMarkdown + (!state.disabled() ? kPopoverInputItemIdentifier : hasActiveChat ? kPopoverPickerItemIdentifier - : @""]; + : @"")]; }, [item lifetime]); return [item autorelease]; diff --git a/Telegram/SourceFiles/support/support_helper.cpp b/Telegram/SourceFiles/support/support_helper.cpp index 08f27db07..286f1fc6c 100644 --- a/Telegram/SourceFiles/support/support_helper.cpp +++ b/Telegram/SourceFiles/support/support_helper.cpp @@ -88,7 +88,7 @@ EditInfoBox::EditInfoBox( _field->setInstantReplaces(Ui::InstantReplaces::Default()); _field->setInstantReplacesEnabled( Core::App().settings().replaceEmojiValue()); - _field->setMarkdownReplacesEnabled(rpl::single(true)); + _field->setMarkdownReplacesEnabled(true); _field->setEditLinkCallback( DefaultEditLinkCallback(controller->uiShow(), _field)); } diff --git a/Telegram/SourceFiles/ui/boxes/edit_factcheck_box.cpp b/Telegram/SourceFiles/ui/boxes/edit_factcheck_box.cpp index 16a5b14af..2c371da40 100644 --- a/Telegram/SourceFiles/ui/boxes/edit_factcheck_box.cpp +++ b/Telegram/SourceFiles/ui/boxes/edit_factcheck_box.cpp @@ -16,7 +16,8 @@ void EditFactcheckBox( not_null box, TextWithEntities current, int limit, - Fn save) { + Fn save, + Fn)> initField) { box->setTitle(tr::lng_factcheck_title()); const auto field = box->addRow(object_ptr( @@ -29,6 +30,7 @@ void EditFactcheckBox( TextUtilities::ConvertEntitiesToTextTags(current.entities) })); AddLengthLimitLabel(field, limit); + initField(field); enum class State { Initial, diff --git a/Telegram/SourceFiles/ui/boxes/edit_factcheck_box.h b/Telegram/SourceFiles/ui/boxes/edit_factcheck_box.h index 7eb104af3..b2ca16479 100644 --- a/Telegram/SourceFiles/ui/boxes/edit_factcheck_box.h +++ b/Telegram/SourceFiles/ui/boxes/edit_factcheck_box.h @@ -9,8 +9,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/layers/generic_box.h" +namespace Ui { +class InputField; +} // namespace Ui + void EditFactcheckBox( not_null box, TextWithEntities current, int limit, - Fn save); + Fn save, + Fn)> initField); diff --git a/Telegram/lib_ui b/Telegram/lib_ui index e7c598aff..0835adcc2 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit e7c598affe724322577ef46d9a07d1dcac3c617b +Subproject commit 0835adcc2d3cb1f2cf0d3630f6d95485864621f9