mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
Extract FieldAutocomplete code.
This commit is contained in:
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/business/data_shortcut_messages.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_document_media.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_user.h"
|
||||
@@ -202,12 +203,6 @@ struct FieldAutocomplete::BotCommandRow {
|
||||
Ui::Text::String descriptionText;
|
||||
};
|
||||
|
||||
FieldAutocomplete::FieldAutocomplete(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller)
|
||||
: FieldAutocomplete(parent, controller->uiShow()) {
|
||||
}
|
||||
|
||||
FieldAutocomplete::FieldAutocomplete(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<Show> show,
|
||||
@@ -252,6 +247,22 @@ std::shared_ptr<Show> FieldAutocomplete::uiShow() const {
|
||||
return _show;
|
||||
}
|
||||
|
||||
void FieldAutocomplete::requestRefresh() {
|
||||
_refreshRequests.fire({});
|
||||
}
|
||||
|
||||
rpl::producer<> FieldAutocomplete::refreshRequests() const {
|
||||
return _refreshRequests.events();
|
||||
}
|
||||
|
||||
void FieldAutocomplete::requestStickersUpdate() {
|
||||
_stickersUpdateRequests.fire({});
|
||||
}
|
||||
|
||||
rpl::producer<> FieldAutocomplete::stickersUpdateRequests() const {
|
||||
return _stickersUpdateRequests.events();
|
||||
}
|
||||
|
||||
auto FieldAutocomplete::mentionChosen() const
|
||||
-> rpl::producer<FieldAutocomplete::MentionChosen> {
|
||||
return _inner->mentionChosen();
|
||||
@@ -378,6 +389,10 @@ void FieldAutocomplete::showStickers(EmojiPtr emoji) {
|
||||
updateFiltered(resetScroll);
|
||||
}
|
||||
|
||||
EmojiPtr FieldAutocomplete::stickersEmoji() const {
|
||||
return _emoji;
|
||||
}
|
||||
|
||||
bool FieldAutocomplete::clearFilteredBotCommands() {
|
||||
if (_brows.empty()) {
|
||||
return false;
|
||||
@@ -1634,4 +1649,165 @@ auto FieldAutocomplete::Inner::scrollToRequested() const
|
||||
return _scrollToRequested.events();
|
||||
}
|
||||
|
||||
void InitFieldAutocomplete(
|
||||
std::unique_ptr<FieldAutocomplete> &autocomplete,
|
||||
FieldAutocompleteDescriptor &&descriptor) {
|
||||
Expects(!autocomplete);
|
||||
|
||||
autocomplete = std::make_unique<FieldAutocomplete>(
|
||||
descriptor.parent,
|
||||
descriptor.show,
|
||||
descriptor.stOverride);
|
||||
const auto raw = autocomplete.get();
|
||||
const auto field = descriptor.field;
|
||||
|
||||
field->rawTextEdit()->installEventFilter(raw);
|
||||
|
||||
raw->mentionChosen(
|
||||
) | rpl::start_with_next([=](FieldAutocomplete::MentionChosen data) {
|
||||
const auto user = data.user;
|
||||
if (data.mention.isEmpty()) {
|
||||
field->insertTag(
|
||||
user->firstName.isEmpty() ? user->name() : user->firstName,
|
||||
PrepareMentionTag(user));
|
||||
} else {
|
||||
field->insertTag('@' + data.mention);
|
||||
}
|
||||
}, raw->lifetime());
|
||||
|
||||
const auto sendCommand = descriptor.sendBotCommand;
|
||||
const auto setText = descriptor.setText;
|
||||
|
||||
raw->hashtagChosen(
|
||||
) | rpl::start_with_next([=](FieldAutocomplete::HashtagChosen data) {
|
||||
field->insertTag(data.hashtag);
|
||||
}, raw->lifetime());
|
||||
|
||||
const auto peer = descriptor.peer;
|
||||
const auto processShortcut = descriptor.processShortcut;
|
||||
const auto shortcutMessages = (processShortcut != nullptr)
|
||||
? &peer->owner().shortcutMessages()
|
||||
: nullptr;
|
||||
raw->botCommandChosen(
|
||||
) | rpl::start_with_next([=](FieldAutocomplete::BotCommandChosen data) {
|
||||
using Method = FieldAutocompleteChooseMethod;
|
||||
const auto byTab = (data.method == Method::ByTab);
|
||||
const auto shortcut = data.user->isSelf();
|
||||
|
||||
// Send bot command at once, if it was not inserted by pressing Tab.
|
||||
if (byTab && data.command.size() > 1) {
|
||||
field->insertTag(data.command);
|
||||
} else if (!shortcut) {
|
||||
sendCommand(data.command);
|
||||
setText(
|
||||
field->getTextWithTagsPart(field->textCursor().position()));
|
||||
} else if (processShortcut) {
|
||||
processShortcut(data.command.mid(1));
|
||||
}
|
||||
}, raw->lifetime());
|
||||
|
||||
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) {
|
||||
raw->stickerChosen(
|
||||
) | rpl::start_with_next(std::move(chosen), raw->lifetime());
|
||||
}
|
||||
|
||||
field->tabbed(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (!raw->isHidden()) {
|
||||
raw->chooseSelected(FieldAutocomplete::ChooseMethod::ByTab);
|
||||
}
|
||||
}, raw->lifetime());
|
||||
|
||||
const auto features = descriptor.features;
|
||||
const auto check = [=] {
|
||||
auto parsed = ParseMentionHashtagBotCommandQuery(field, features());
|
||||
if (parsed.query.isEmpty()) {
|
||||
} else if (parsed.query[0] == '#'
|
||||
&& cRecentWriteHashtags().isEmpty()
|
||||
&& cRecentSearchHashtags().isEmpty()) {
|
||||
peer->session().local().readRecentHashtagsAndBots();
|
||||
} else if (parsed.query[0] == '@'
|
||||
&& cRecentInlineBots().isEmpty()) {
|
||||
peer->session().local().readRecentHashtagsAndBots();
|
||||
} else if (parsed.query[0] == '/'
|
||||
&& peer->isUser()
|
||||
&& !peer->asUser()->isBot()
|
||||
&& (!shortcutMessages
|
||||
|| shortcutMessages->shortcuts().list.empty())) {
|
||||
parsed = {};
|
||||
}
|
||||
raw->showFiltered(peer, parsed.query, parsed.fromStart);
|
||||
};
|
||||
|
||||
const auto updateStickersByEmoji = [=] {
|
||||
const auto errorForStickers = Data::RestrictionError(
|
||||
peer,
|
||||
ChatRestriction::SendStickers);
|
||||
if (features().suggestStickersByEmoji && !errorForStickers) {
|
||||
const auto &text = field->getTextWithTags().text;
|
||||
auto length = 0;
|
||||
if (const auto emoji = Ui::Emoji::Find(text, &length)) {
|
||||
if (text.size() <= length) {
|
||||
raw->showStickers(emoji);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
raw->showStickers(nullptr);
|
||||
};
|
||||
|
||||
raw->refreshRequests(
|
||||
) | rpl::start_with_next(check, raw->lifetime());
|
||||
|
||||
raw->stickersUpdateRequests(
|
||||
) | rpl::start_with_next(updateStickersByEmoji, raw->lifetime());
|
||||
|
||||
peer->owner().botCommandsChanges(
|
||||
) | rpl::filter([=](not_null<PeerData*> changed) {
|
||||
return (peer == changed);
|
||||
}) | rpl::start_with_next([=] {
|
||||
if (raw->clearFilteredBotCommands()) {
|
||||
check();
|
||||
}
|
||||
}, raw->lifetime());
|
||||
|
||||
peer->owner().stickers().updated(
|
||||
Data::StickersType::Stickers
|
||||
) | rpl::start_with_next(updateStickersByEmoji, raw->lifetime());
|
||||
|
||||
QObject::connect(
|
||||
field->rawTextEdit(),
|
||||
&QTextEdit::cursorPositionChanged,
|
||||
raw,
|
||||
check,
|
||||
Qt::QueuedConnection);
|
||||
|
||||
field->changes() | rpl::start_with_next(
|
||||
updateStickersByEmoji,
|
||||
raw->lifetime());
|
||||
|
||||
peer->session().changes().peerUpdates(
|
||||
Data::PeerUpdate::Flag::Rights
|
||||
) | rpl::filter([=](const Data::PeerUpdate &update) {
|
||||
return (update.peer == peer);
|
||||
}) | rpl::start_with_next(updateStickersByEmoji, raw->lifetime());
|
||||
|
||||
if (shortcutMessages) {
|
||||
shortcutMessages->shortcutsChanged(
|
||||
) | rpl::start_with_next(check, raw->lifetime());
|
||||
}
|
||||
|
||||
raw->setSendMenuDetails(std::move(descriptor.sendMenuDetails));
|
||||
raw->hideFast();
|
||||
}
|
||||
|
||||
} // namespace ChatHelpers
|
||||
|
||||
Reference in New Issue
Block a user