Allow sending quick replies like bot commands.

This commit is contained in:
John Preston 2024-03-04 17:00:25 +04:00
parent 37f5160d1c
commit 5e82860376
7 changed files with 75 additions and 5 deletions

View file

@ -953,6 +953,7 @@ void ApiWrap::requestMoreDialogsIfNeeded() {
} }
} }
requestContacts(); requestContacts();
_session->data().shortcutMessages().preloadShortcuts();
} }
void ApiWrap::updateDialogsOffset( void ApiWrap::updateDialogsOffset(
@ -3606,6 +3607,17 @@ void ApiWrap::cancelLocalItem(not_null<HistoryItem*> item) {
} }
} }
void ApiWrap::sendShortcutMessages(
not_null<PeerData*> peer,
BusinessShortcutId id) {
request(MTPmessages_SendQuickReplyMessages(
peer->input,
MTP_int(id)
)).done([=](const MTPUpdates &result) {
applyUpdates(result);
}).send();
}
void ApiWrap::sendMessage(MessageToSend &&message) { void ApiWrap::sendMessage(MessageToSend &&message) {
const auto history = message.action.history; const auto history = message.action.history;
const auto peer = history->peer; const auto peer = history->peer;

View file

@ -337,6 +337,9 @@ public:
void cancelLocalItem(not_null<HistoryItem*> item); void cancelLocalItem(not_null<HistoryItem*> item);
void sendShortcutMessages(
not_null<PeerData*> peer,
BusinessShortcutId id);
void sendMessage(MessageToSend &&message); void sendMessage(MessageToSend &&message);
void sendBotStart( void sendBotStart(
not_null<UserData*> bot, not_null<UserData*> bot,

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "chat_helpers/field_autocomplete.h" #include "chat_helpers/field_autocomplete.h"
#include "data/business/data_shortcut_messages.h"
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_document_media.h" #include "data/data_document_media.h"
#include "data/data_channel.h" #include "data/data_channel.h"
@ -27,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/storage_account.h" #include "storage/storage_account.h"
#include "core/application.h" #include "core/application.h"
#include "core/core_settings.h" #include "core/core_settings.h"
#include "lang/lang_keys.h"
#include "lottie/lottie_single_player.h" #include "lottie/lottie_single_player.h"
#include "media/clip/media_clip_reader.h" #include "media/clip/media_clip_reader.h"
#include "ui/widgets/popup_menu.h" #include "ui/widgets/popup_menu.h"
@ -636,6 +638,27 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
} }
} }
} }
const auto shortcuts = _user
? _user->owner().shortcutMessages().shortcuts().list
: base::flat_map<BusinessShortcutId, Data::Shortcut>();
if (!hasUsername && !shortcuts.empty()) {
const auto self = _user->session().user();
for (const auto &[id, shortcut] : shortcuts) {
if (shortcut.count < 1) {
continue;
} else if (!listAllSuggestions) {
if (!shortcut.name.startsWith(_filter, Qt::CaseInsensitive)) {
continue;
}
}
brows.push_back(BotCommandRow{
self,
shortcut.name,
tr::lng_forum_messages(tr::now, lt_count, shortcut.count),
self->activeUserpicView()
});
}
}
} }
rowsUpdated( rowsUpdated(
std::move(mrows), std::move(mrows),
@ -1247,7 +1270,7 @@ bool FieldAutocomplete::Inner::chooseAtIndex(
command, command,
insertUsername ? ('@' + PrimaryUsername(user)) : QString()); insertUsername ? ('@' + PrimaryUsername(user)) : QString());
_botCommandChosen.fire({ commandString, method }); _botCommandChosen.fire({ user, commandString, method });
return true; return true;
} }
} }

View file

@ -96,6 +96,7 @@ public:
ChooseMethod method = ChooseMethod::ByEnter; ChooseMethod method = ChooseMethod::ByEnter;
}; };
struct BotCommandChosen { struct BotCommandChosen {
not_null<UserData*> user;
QString command; QString command;
ChooseMethod method = ChooseMethod::ByEnter; ChooseMethod method = ChooseMethod::ByEnter;
}; };

View file

@ -497,6 +497,16 @@ Shortcut ShortcutMessages::lookupShortcut(BusinessShortcutId id) const {
return i->second; return i->second;
} }
BusinessShortcutId ShortcutMessages::lookupShortcutId(
const QString &name) const {
for (const auto &[id, shortcut] : _shortcuts.list) {
if (!shortcut.name.compare(name, Qt::CaseInsensitive)) {
return id;
}
}
return {};
}
void ShortcutMessages::editShortcut( void ShortcutMessages::editShortcut(
BusinessShortcutId id, BusinessShortcutId id,
QString name, QString name,

View file

@ -78,6 +78,8 @@ public:
[[nodiscard]] rpl::producer<ShortcutIdChange> shortcutIdChanged() const; [[nodiscard]] rpl::producer<ShortcutIdChange> shortcutIdChanged() const;
[[nodiscard]] BusinessShortcutId emplaceShortcut(QString name); [[nodiscard]] BusinessShortcutId emplaceShortcut(QString name);
[[nodiscard]] Shortcut lookupShortcut(BusinessShortcutId id) const; [[nodiscard]] Shortcut lookupShortcut(BusinessShortcutId id) const;
[[nodiscard]] BusinessShortcutId lookupShortcutId(
const QString &name) const;
void editShortcut( void editShortcut(
BusinessShortcutId id, BusinessShortcutId id,
QString name, QString name,

View file

@ -52,6 +52,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/qt/qt_key_modifiers.h" #include "base/qt/qt_key_modifiers.h"
#include "base/unixtime.h" #include "base/unixtime.h"
#include "base/call_delayed.h" #include "base/call_delayed.h"
#include "data/business/data_shortcut_messages.h"
#include "data/notify/data_notify_settings.h" #include "data/notify/data_notify_settings.h"
#include "data/data_changes.h" #include "data/data_changes.h"
#include "data/data_drafts.h" #include "data/data_drafts.h"
@ -431,7 +432,20 @@ HistoryWidget::HistoryWidget(
_fieldAutocomplete->botCommandChosen( _fieldAutocomplete->botCommandChosen(
) | rpl::start_with_next([=](FieldAutocomplete::BotCommandChosen data) { ) | rpl::start_with_next([=](FieldAutocomplete::BotCommandChosen data) {
insertHashtagOrBotCommand(data.command, data.method); using Method = FieldAutocomplete::ChooseMethod;
const auto messages = &data.user->owner().shortcutMessages();
const auto shortcutId = (_peer
&& data.user->isSelf()
&& data.method != Method::ByTab)
? messages->lookupShortcutId(data.command.mid(1))
: BusinessShortcutId();
if (shortcutId) {
session().api().sendShortcutMessages(_peer, shortcutId);
session().api().finishForwarding(prepareSendAction({}));
setFieldText(_field->getTextWithTagsPart(_field->textCursor().position()));
} else {
insertHashtagOrBotCommand(data.command, data.method);
}
}, lifetime()); }, lifetime());
_fieldAutocomplete->setModerateKeyActivateCallback([=](int key) { _fieldAutocomplete->setModerateKeyActivateCallback([=](int key) {
@ -1410,9 +1424,14 @@ AutocompleteQuery HistoryWidget::parseMentionHashtagBotCommandQuery() const {
} else if (result.query[0] == '@' } else if (result.query[0] == '@'
&& cRecentInlineBots().isEmpty()) { && cRecentInlineBots().isEmpty()) {
session().local().readRecentHashtagsAndBots(); session().local().readRecentHashtagsAndBots();
} else if (result.query[0] == '/' } else if (result.query[0] == '/') {
&& ((_peer->isUser() && !_peer->asUser()->isBot()) || _editMsgId)) { if (_editMsgId) {
return AutocompleteQuery(); return {};
} else if (_peer->isUser()
&& !_peer->asUser()->isBot()
&& _peer->owner().shortcutMessages().shortcuts().list.empty()) {
return {};
}
} }
return result; return result;
} }