From 3eec43cacd65be84b01f450a0f5203b0685c9ecc Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 13 Sep 2024 20:04:47 +0400 Subject: [PATCH] Add FieldAutocomplete to SendFilesBox. --- Telegram/SourceFiles/boxes/send_files_box.cpp | 64 +++++++++++++++++++ Telegram/SourceFiles/boxes/send_files_box.h | 6 ++ .../chat_helpers/field_autocomplete.cpp | 24 ++++--- 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index d1757da15..a6e853eca 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "chat_helpers/message_field.h" #include "menu/menu_send.h" #include "chat_helpers/emoji_suggestions_widget.h" +#include "chat_helpers/field_autocomplete.h" #include "chat_helpers/tabbed_panel.h" #include "chat_helpers/tabbed_selector.h" #include "editor/photo_editor_layer_widget.h" @@ -1273,6 +1274,7 @@ void SendFilesBox::setupCaption() { [=] { return show->paused(Window::GifPauseReason::Layer); }, allow, &_st.files.caption); + setupCaptionAutocomplete(); Ui::Emoji::SuggestionsController::Init( getDelegate()->outerContainer(), _caption, @@ -1332,6 +1334,60 @@ void SendFilesBox::setupCaption() { }, _caption->lifetime()); } +void SendFilesBox::setupCaptionAutocomplete() { + if (!_captionToPeer || !_caption) { + return; + } + const auto parent = getDelegate()->outerContainer(); + ChatHelpers::InitFieldAutocomplete(_autocomplete, { + .parent = parent, + .show = _show, + .field = _caption.data(), + .peer = _captionToPeer, + .features = [=] { + auto result = ChatHelpers::ComposeFeatures(); + result.autocompleteCommands = false; + result.suggestStickersByEmoji = false; + return result; + }, + .sendMenuDetails = _sendMenuDetails, + }); + const auto raw = _autocomplete.get(); + const auto scheduled = std::make_shared(); + const auto recountPostponed = [=] { + if (*scheduled) { + return; + } + *scheduled = true; + Ui::PostponeCall(raw, [=] { + *scheduled = false; + + auto full = parent->rect(); + auto field = Ui::MapFrom(parent, this, _caption->geometry()); + _autocomplete->setBoundings(QRect( + field.x() - _caption->x(), + st::defaultBox.margin.top(), + width(), + (field.y() + + _st.files.caption.textMargins.top() + + _st.files.caption.placeholderShift + + _st.files.caption.placeholderFont->height + - st::defaultBox.margin.top()))); + }); + }; + for (auto w = (QWidget*)_caption.data(); w; w = w->parentWidget()) { + base::install_event_filter(raw, w, [=](not_null e) { + if (e->type() == QEvent::Move || e->type() == QEvent::Resize) { + recountPostponed(); + } + return base::EventFilterResult::Continue; + }); + if (w == parent) { + break; + } + } +} + void SendFilesBox::checkCharsLimitation() { const auto limits = Data::PremiumLimits(&_show->session()); const auto caption = (_caption && !_caption->isHidden()) @@ -1647,6 +1703,14 @@ void SendFilesBox::updateControlsGeometry() { _scroll->move(0, _titleHeight.current()); } +void SendFilesBox::showFinished() { + if (const auto raw = _autocomplete.get()) { + InvokeQueued(raw, [=] { + raw->raise(); + }); + } +} + void SendFilesBox::setInnerFocus() { if (_caption && !_caption->isHidden()) { _caption->setFocusFast(); diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index 8f3432ebd..6646ec107 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -28,6 +28,7 @@ enum class SendType; namespace ChatHelpers { class TabbedPanel; class Show; +class FieldAutocomplete; } // namespace ChatHelpers namespace Ui { @@ -126,6 +127,8 @@ public: _cancelledCallback = std::move(callback); } + void showFinished() override; + ~SendFilesBox(); protected: @@ -206,6 +209,7 @@ private: void refreshControls(bool initial = false); void setupSendWayControls(); void setupCaption(); + void setupCaptionAutocomplete(); void setupEmojiPanel(); void updateSendWayControls(); @@ -257,6 +261,7 @@ private: SendFilesLimits _limits = {}; Fn _sendMenuDetails; Fn _sendMenuCallback; + PeerData *_captionToPeer = nullptr; SendFilesCheck _check; SendFilesConfirmed _confirmedCallback; @@ -268,6 +273,7 @@ private: bool _invertCaption = false; object_ptr _caption = { nullptr }; + std::unique_ptr _autocomplete; TextWithTags _prefilledCaptionText; object_ptr _emojiToggle = { nullptr }; base::unique_qptr _emojiPanel; diff --git a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp index d956acfa6..b3a9250d8 100644 --- a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp +++ b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp @@ -1684,12 +1684,16 @@ void InitFieldAutocomplete( }, raw->lifetime()); const auto peer = descriptor.peer; + const auto features = descriptor.features; const auto processShortcut = descriptor.processShortcut; const auto shortcutMessages = (processShortcut != nullptr) ? &peer->owner().shortcutMessages() : nullptr; raw->botCommandChosen( ) | rpl::start_with_next([=](FieldAutocomplete::BotCommandChosen data) { + if (!features().autocompleteCommands) { + return; + } using Method = FieldAutocompleteChooseMethod; const auto byTab = (data.method == Method::ByTab); const auto shortcut = data.user->isSelf(); @@ -1708,16 +1712,17 @@ void InitFieldAutocomplete( raw->setModerateKeyActivateCallback(std::move(descriptor.moderateKeyActivateCallback)); - const auto stickerChoosing = descriptor.stickerChoosing; - raw->choosingProcesses( - ) | rpl::start_with_next([=](FieldAutocomplete::Type type) { - if (type == FieldAutocomplete::Type::Stickers) { - stickerChoosing(); - } - }, raw->lifetime()); - if (auto chosen = descriptor.stickerChosen) { + if (const auto stickerChoosing = descriptor.stickerChoosing) { + raw->choosingProcesses( + ) | rpl::start_with_next([=](FieldAutocomplete::Type type) { + if (type == FieldAutocomplete::Type::Stickers) { + stickerChoosing(); + } + }, raw->lifetime()); + } + if (const auto chosen = descriptor.stickerChosen) { raw->stickerChosen( - ) | rpl::start_with_next(std::move(chosen), raw->lifetime()); + ) | rpl::start_with_next(chosen, raw->lifetime()); } field->tabbed( @@ -1727,7 +1732,6 @@ void InitFieldAutocomplete( } }, raw->lifetime()); - const auto features = descriptor.features; const auto check = [=] { auto parsed = ParseMentionHashtagBotCommandQuery(field, features()); if (parsed.query.isEmpty()) {