Skip to content

Commit

Permalink
Add mention/hashtag autocomplete to GIF caption.
Browse files Browse the repository at this point in the history
  • Loading branch information
john-preston committed Sep 30, 2024
1 parent 632639d commit 86c0442
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 3 deletions.
70 changes: 68 additions & 2 deletions Telegram/SourceFiles/boxes/send_gif_with_caption_box.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ For license and copyright information please follow this link:
*/
#include "boxes/send_gif_with_caption_box.h"

#include "base/event_filter.h"
#include "boxes/premium_preview_box.h"
#include "chat_helpers/field_autocomplete.h"
#include "chat_helpers/message_field.h"
#include "chat_helpers/tabbed_panel.h"
#include "chat_helpers/tabbed_selector.h"
Expand All @@ -30,9 +32,10 @@ For license and copyright information please follow this link:
#include "ui/controls/emoji_button.h"
#include "ui/controls/emoji_button_factory.h"
#include "ui/layers/generic_box.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/rect.h"
#include "ui/ui_utility.h"
#include "ui/vertical_list.h"
#include "ui/widgets/fields/input_field.h"
#include "window/window_controller.h"
#include "window/window_session_controller.h"
#include "styles/style_boxes.h"
Expand Down Expand Up @@ -226,6 +229,7 @@ namespace {
void SendGifWithCaptionBox(
not_null<Ui::GenericBox*> box,
not_null<DocumentData*> document,
not_null<PeerData*> peer,
const SendMenu::Details &details,
Fn<void(Api::SendOptions, TextWithTags)> done) {
const auto window = Core::App().findWindow(box);
Expand Down Expand Up @@ -255,6 +259,61 @@ void SendGifWithCaptionBox(
return true;
});

const auto sendMenuDetails = [=] { return details; };
struct Autocomplete {
std::unique_ptr<ChatHelpers::FieldAutocomplete> dropdown;
bool geometryUpdateScheduled = false;
};
const auto autocomplete = box->lifetime().make_state<Autocomplete>();
const auto outer = box->getDelegate()->outerContainer();
ChatHelpers::InitFieldAutocomplete(autocomplete->dropdown, {
.parent = outer,
.show = controller->uiShow(),
.field = input,
.peer = peer,
.features = [=] {
auto result = ChatHelpers::ComposeFeatures();
result.autocompleteCommands = false;
result.suggestStickersByEmoji = false;
return result;
},
.sendMenuDetails = sendMenuDetails,
});
const auto raw = autocomplete->dropdown.get();
const auto recountPostponed = [=] {
if (autocomplete->geometryUpdateScheduled) {
return;
}
autocomplete->geometryUpdateScheduled = true;
Ui::PostponeCall(raw, [=] {
autocomplete->geometryUpdateScheduled = false;

const auto from = input->parentWidget();
auto field = Ui::MapFrom(outer, from, input->geometry());
const auto &st = st::defaultComposeFiles;
autocomplete->dropdown->setBoundings(QRect(
field.x() - input->x(),
st::defaultBox.margin.top(),
input->width(),
(field.y()
+ st.caption.textMargins.top()
+ st.caption.placeholderShift
+ st.caption.placeholderFont->height
- st::defaultBox.margin.top())));
});
};
for (auto w = (QWidget*)input; w; w = w->parentWidget()) {
base::install_event_filter(raw, w, [=](not_null<QEvent*> e) {
if (e->type() == QEvent::Move || e->type() == QEvent::Resize) {
recountPostponed();
}
return base::EventFilterResult::Continue;
});
if (w == outer) {
break;
}
}

const auto send = [=](Api::SendOptions options) {
done(std::move(options), input->getTextWithTags());
};
Expand All @@ -264,8 +323,15 @@ void SendGifWithCaptionBox(
SendMenu::SetupMenuAndShortcuts(
confirm,
controller->uiShow(),
[=] { return details; },
sendMenuDetails,
SendMenu::DefaultCallback(controller->uiShow(), send));
box->setShowFinishedCallback([=] {
if (const auto raw = autocomplete->dropdown.get()) {
InvokeQueued(raw, [=] {
raw->raise();
});
}
});
box->addButton(tr::lng_cancel(), [=] {
box->closeBox();
});
Expand Down
2 changes: 2 additions & 0 deletions Telegram/SourceFiles/boxes/send_gif_with_caption_box.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ For license and copyright information please follow this link:
*/
#pragma once

class PeerData;
class DocumentData;

namespace Api {
Expand All @@ -24,6 +25,7 @@ class GenericBox;
void SendGifWithCaptionBox(
not_null<Ui::GenericBox*> box,
not_null<DocumentData*> document,
not_null<PeerData*> peer,
const SendMenu::Details &details,
Fn<void(Api::SendOptions, TextWithTags)> done);

Expand Down
4 changes: 3 additions & 1 deletion Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,17 +409,19 @@ base::unique_qptr<Ui::PopupMenu> GifsListWidget::fillContextMenu(
SendMenu::DefaultCallback(_show, send),
icons);

if (!isInlineResult) {
if (!isInlineResult && _inlineQueryPeer) {
auto done = crl::guard(this, [=](
Api::SendOptions options,
TextWithTags text) {
selectInlineResult(selected, options, true, std::move(text));
});
const auto show = _show;
const auto peer = _inlineQueryPeer;
menu->addAction(tr::lng_send_gif_with_caption(tr::now), [=] {
show->show(Box(
Ui::SendGifWithCaptionBox,
item->getDocument(),
peer,
copyDetails,
std::move(done)));
}, &st::menuIconEdit);
Expand Down

0 comments on commit 86c0442

Please sign in to comment.