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();
_session->data().shortcutMessages().preloadShortcuts();
}
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) {
const auto history = message.action.history;
const auto peer = history->peer;

View File

@ -337,6 +337,9 @@ public:
void cancelLocalItem(not_null<HistoryItem*> item);
void sendShortcutMessages(
not_null<PeerData*> peer,
BusinessShortcutId id);
void sendMessage(MessageToSend &&message);
void sendBotStart(
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 "data/business/data_shortcut_messages.h"
#include "data/data_document.h"
#include "data/data_document_media.h"
#include "data/data_channel.h"
@ -27,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/storage_account.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "lang/lang_keys.h"
#include "lottie/lottie_single_player.h"
#include "media/clip/media_clip_reader.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(
std::move(mrows),
@ -1247,7 +1270,7 @@ bool FieldAutocomplete::Inner::chooseAtIndex(
command,
insertUsername ? ('@' + PrimaryUsername(user)) : QString());
_botCommandChosen.fire({ commandString, method });
_botCommandChosen.fire({ user, commandString, method });
return true;
}
}

View File

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

View File

@ -497,6 +497,16 @@ Shortcut ShortcutMessages::lookupShortcut(BusinessShortcutId id) const {
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(
BusinessShortcutId id,
QString name,

View File

@ -78,6 +78,8 @@ public:
[[nodiscard]] rpl::producer<ShortcutIdChange> shortcutIdChanged() const;
[[nodiscard]] BusinessShortcutId emplaceShortcut(QString name);
[[nodiscard]] Shortcut lookupShortcut(BusinessShortcutId id) const;
[[nodiscard]] BusinessShortcutId lookupShortcutId(
const QString &name) const;
void editShortcut(
BusinessShortcutId id,
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/unixtime.h"
#include "base/call_delayed.h"
#include "data/business/data_shortcut_messages.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_changes.h"
#include "data/data_drafts.h"
@ -431,7 +432,20 @@ HistoryWidget::HistoryWidget(
_fieldAutocomplete->botCommandChosen(
) | 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());
_fieldAutocomplete->setModerateKeyActivateCallback([=](int key) {
@ -1410,9 +1424,14 @@ AutocompleteQuery HistoryWidget::parseMentionHashtagBotCommandQuery() const {
} else if (result.query[0] == '@'
&& cRecentInlineBots().isEmpty()) {
session().local().readRecentHashtagsAndBots();
} else if (result.query[0] == '/'
&& ((_peer->isUser() && !_peer->asUser()->isBot()) || _editMsgId)) {
return AutocompleteQuery();
} else if (result.query[0] == '/') {
if (_editMsgId) {
return {};
} else if (_peer->isUser()
&& !_peer->asUser()->isBot()
&& _peer->owner().shortcutMessages().shortcuts().list.empty()) {
return {};
}
}
return result;
}