mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Support attach webview bots in topics.
This commit is contained in:
parent
b3f9b16eb2
commit
aa5f9467f2
11 changed files with 165 additions and 66 deletions
|
@ -1771,8 +1771,8 @@ messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = mes
|
|||
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
||||
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
||||
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
|
||||
messages.requestWebView#fc87a53c flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = WebViewResult;
|
||||
messages.prolongWebView#ea5fbcce flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = Bool;
|
||||
messages.requestWebView#178b480b flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = WebViewResult;
|
||||
messages.prolongWebView#7ff34309 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = Bool;
|
||||
messages.requestSimpleWebView#299bec8e flags:# bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult;
|
||||
messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent;
|
||||
messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates;
|
||||
|
|
|
@ -441,7 +441,7 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
|
|||
if (const auto bot = item->getMessageBot()) {
|
||||
bot->session().attachWebView().request(
|
||||
controller,
|
||||
bot,
|
||||
Api::SendAction(bot->owner().history(bot)),
|
||||
bot,
|
||||
{ .text = button->text, .url = button->data });
|
||||
}
|
||||
|
|
|
@ -2353,6 +2353,7 @@ void HistoryWidget::refreshAttachBotsMenu() {
|
|||
_attachBotsMenu = InlineBots::MakeAttachBotsMenu(
|
||||
this,
|
||||
_history->peer,
|
||||
[=] { return prepareSendAction({}); },
|
||||
[=](bool compress) { chooseAttach(compress); });
|
||||
if (!_attachBotsMenu) {
|
||||
return;
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace Api {
|
||||
enum class SendProgressType;
|
||||
struct SendOptions;
|
||||
struct SendAction;
|
||||
} // namespace Api
|
||||
|
||||
class History;
|
||||
|
@ -37,6 +38,7 @@ struct SetHistoryArgs {
|
|||
required<History*> history;
|
||||
MsgId topicRootId = 0;
|
||||
Fn<bool()> showSlowmodeError;
|
||||
Fn<Api::SendAction()> sendActionFactory;
|
||||
rpl::producer<int> slowmodeSecondsLeft;
|
||||
rpl::producer<bool> sendDisabledBySlowmode;
|
||||
rpl::producer<std::optional<QString>> writeRestriction;
|
||||
|
|
|
@ -43,6 +43,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/controls/history_view_voice_record_bar.h"
|
||||
#include "history/view/controls/history_view_ttl_button.h"
|
||||
#include "history/view/history_view_webpage_preview.h"
|
||||
#include "inline_bots/bot_attach_web_view.h"
|
||||
#include "inline_bots/inline_results_widget.h"
|
||||
#include "inline_bots/inline_bot_result.h"
|
||||
#include "lang/lang_keys.h"
|
||||
|
@ -54,6 +55,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/text/text_options.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/widgets/dropdown_menu.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/controls/emoji_button.h"
|
||||
#include "ui/controls/send_button.h"
|
||||
|
@ -894,6 +896,7 @@ void ComposeControls::setHistory(SetHistoryArgs &&args) {
|
|||
Expects(!_history && *args.history);
|
||||
|
||||
_showSlowmodeError = std::move(args.showSlowmodeError);
|
||||
_sendActionFactory = std::move(args.sendActionFactory);
|
||||
_topicRootId = args.topicRootId;
|
||||
_slowmodeSecondsLeft = rpl::single(0)
|
||||
| rpl::then(std::move(args.slowmodeSecondsLeft));
|
||||
|
@ -918,6 +921,7 @@ void ComposeControls::setHistory(SetHistoryArgs &&args) {
|
|||
updateControlsVisibility();
|
||||
updateFieldPlaceholder();
|
||||
updateSendAsButton();
|
||||
updateAttachBotsMenu();
|
||||
//if (!_history) {
|
||||
// return;
|
||||
//}
|
||||
|
@ -1053,9 +1057,9 @@ rpl::producer<MessageToEdit> ComposeControls::editRequests() const {
|
|||
std::move(submits) | filter | toValue);
|
||||
}
|
||||
|
||||
rpl::producer<> ComposeControls::attachRequests() const {
|
||||
rpl::producer<std::optional<bool>> ComposeControls::attachRequests() const {
|
||||
return rpl::merge(
|
||||
_attachToggle->clicks() | rpl::to_empty,
|
||||
_attachToggle->clicks() | rpl::map_to(std::optional<bool>()),
|
||||
_attachRequests.events()
|
||||
) | rpl::filter([=] {
|
||||
if (isEditingMessage()) {
|
||||
|
@ -1090,6 +1094,9 @@ void ComposeControls::showStarted() {
|
|||
if (_tabbedPanel) {
|
||||
_tabbedPanel->hideFast();
|
||||
}
|
||||
if (_attachBotsMenu) {
|
||||
_attachBotsMenu->hideFast();
|
||||
}
|
||||
if (_voiceRecordBar) {
|
||||
_voiceRecordBar->hideFast();
|
||||
}
|
||||
|
@ -1107,6 +1114,9 @@ void ComposeControls::showFinished() {
|
|||
if (_tabbedPanel) {
|
||||
_tabbedPanel->hideFast();
|
||||
}
|
||||
if (_attachBotsMenu) {
|
||||
_attachBotsMenu->hideFast();
|
||||
}
|
||||
if (_voiceRecordBar) {
|
||||
_voiceRecordBar->hideFast();
|
||||
}
|
||||
|
@ -1127,6 +1137,9 @@ void ComposeControls::raisePanels() {
|
|||
if (_tabbedPanel) {
|
||||
_tabbedPanel->raise();
|
||||
}
|
||||
if (_attachBotsMenu) {
|
||||
_attachBotsMenu->raise();
|
||||
}
|
||||
if (_raiseEmojiSuggestions) {
|
||||
_raiseEmojiSuggestions();
|
||||
}
|
||||
|
@ -1204,6 +1217,9 @@ void ComposeControls::hidePanelsAnimated() {
|
|||
if (_tabbedPanel) {
|
||||
_tabbedPanel->hideAnimated();
|
||||
}
|
||||
if (_attachBotsMenu) {
|
||||
_attachBotsMenu->hideAnimated();
|
||||
}
|
||||
if (_inlineResults) {
|
||||
_inlineResults->hideAnimated();
|
||||
}
|
||||
|
@ -1350,6 +1366,11 @@ void ComposeControls::init() {
|
|||
saveFieldToHistoryLocalDraft();
|
||||
}, _wrap->lifetime());
|
||||
|
||||
session().attachWebView().attachBotsUpdates(
|
||||
) | rpl::start_with_next([=] {
|
||||
updateAttachBotsMenu();
|
||||
}, _wrap->lifetime());
|
||||
|
||||
orderControls();
|
||||
}
|
||||
|
||||
|
@ -2226,10 +2247,12 @@ void ComposeControls::updateOuterGeometry(QRect rect) {
|
|||
if (_inlineResults) {
|
||||
_inlineResults->moveBottom(rect.y());
|
||||
}
|
||||
const auto bottom = rect.y() + rect.height() - _attachToggle->height();
|
||||
if (_tabbedPanel) {
|
||||
_tabbedPanel->moveBottomRight(
|
||||
rect.y() + rect.height() - _attachToggle->height(),
|
||||
rect.x() + rect.width());
|
||||
_tabbedPanel->moveBottomRight(bottom, rect.x() + rect.width());
|
||||
}
|
||||
if (_attachBotsMenu) {
|
||||
_attachBotsMenu->moveToLeft(0, bottom - _attachBotsMenu->height());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2274,6 +2297,28 @@ bool ComposeControls::updateSendAsButton() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ComposeControls::updateAttachBotsMenu() {
|
||||
_attachBotsMenu = nullptr;
|
||||
if (!_history || !_sendActionFactory) {
|
||||
return;
|
||||
}
|
||||
_attachBotsMenu = InlineBots::MakeAttachBotsMenu(
|
||||
_parent,
|
||||
_history->peer,
|
||||
_sendActionFactory,
|
||||
[=](bool compress) { _attachRequests.fire_copy(compress); });
|
||||
if (!_attachBotsMenu) {
|
||||
return;
|
||||
}
|
||||
_attachBotsMenu->setOrigin(
|
||||
Ui::PanelAnimation::Origin::BottomLeft);
|
||||
_attachToggle->installEventFilter(_attachBotsMenu.get());
|
||||
_attachBotsMenu->heightValue(
|
||||
) | rpl::start_with_next([=] {
|
||||
updateOuterGeometry(_wrap->geometry());
|
||||
}, _attachBotsMenu->lifetime());
|
||||
}
|
||||
|
||||
void ComposeControls::paintBackground(QRect clip) {
|
||||
Painter p(_wrap.get());
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ class IconButton;
|
|||
class EmojiButton;
|
||||
class SendAsButton;
|
||||
class SilentToggle;
|
||||
class DropdownMenu;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Main {
|
||||
|
@ -123,7 +124,7 @@ public:
|
|||
[[nodiscard]] rpl::producer<VoiceToSend> sendVoiceRequests() const;
|
||||
[[nodiscard]] rpl::producer<QString> sendCommandRequests() const;
|
||||
[[nodiscard]] rpl::producer<MessageToEdit> editRequests() const;
|
||||
[[nodiscard]] rpl::producer<> attachRequests() const;
|
||||
[[nodiscard]] rpl::producer<std::optional<bool>> attachRequests() const;
|
||||
[[nodiscard]] rpl::producer<FileChosen> fileChosen() const;
|
||||
[[nodiscard]] rpl::producer<PhotoChosen> photoChosen() const;
|
||||
[[nodiscard]] rpl::producer<Data::MessagePosition> scrollRequests() const;
|
||||
|
@ -215,6 +216,7 @@ private:
|
|||
void updateSendButtonType();
|
||||
void updateMessagesTTLShown();
|
||||
bool updateSendAsButton();
|
||||
void updateAttachBotsMenu();
|
||||
void updateHeight();
|
||||
void updateWrappingVisibility();
|
||||
void updateControlsVisibility();
|
||||
|
@ -287,6 +289,7 @@ private:
|
|||
const not_null<Window::SessionController*> _window;
|
||||
History *_history = nullptr;
|
||||
Fn<bool()> _showSlowmodeError;
|
||||
Fn<Api::SendAction()> _sendActionFactory;
|
||||
rpl::variable<int> _slowmodeSecondsLeft;
|
||||
rpl::variable<bool> _sendDisabledBySlowmode;
|
||||
rpl::variable<std::optional<QString>> _writeRestriction;
|
||||
|
@ -308,6 +311,7 @@ private:
|
|||
|
||||
std::unique_ptr<InlineBots::Layout::Widget> _inlineResults;
|
||||
std::unique_ptr<ChatHelpers::TabbedPanel> _tabbedPanel;
|
||||
std::unique_ptr<Ui::DropdownMenu> _attachBotsMenu;
|
||||
std::unique_ptr<FieldAutocomplete> _autocomplete;
|
||||
|
||||
friend class FieldHeader;
|
||||
|
@ -326,7 +330,7 @@ private:
|
|||
rpl::event_stream<QString> _sendCommandRequests;
|
||||
rpl::event_stream<not_null<QKeyEvent*>> _scrollKeyEvents;
|
||||
rpl::event_stream<not_null<QKeyEvent*>> _editLastMessageRequests;
|
||||
rpl::event_stream<> _attachRequests;
|
||||
rpl::event_stream<std::optional<bool>> _attachRequests;
|
||||
rpl::event_stream<ReplyNextRequest> _replyNextRequests;
|
||||
|
||||
TextUpdateEvents _textUpdateEvents = TextUpdateEvents()
|
||||
|
|
|
@ -670,6 +670,7 @@ void RepliesWidget::setupComposeControls() {
|
|||
_composeControls->setHistory({
|
||||
.history = _history.get(),
|
||||
.showSlowmodeError = [=] { return showSlowmodeError(); },
|
||||
.sendActionFactory = [=] { return prepareSendAction({}); },
|
||||
.slowmodeSecondsLeft = std::move(slowmodeSecondsLeft),
|
||||
.sendDisabledBySlowmode = std::move(sendDisabledBySlowmode),
|
||||
.writeRestriction = std::move(writeRestriction),
|
||||
|
@ -720,12 +721,12 @@ void RepliesWidget::setupComposeControls() {
|
|||
_composeControls->attachRequests(
|
||||
) | rpl::filter([=] {
|
||||
return !_choosingAttach;
|
||||
}) | rpl::start_with_next([=] {
|
||||
}) | rpl::start_with_next([=](std::optional<bool> overrideCompress) {
|
||||
_choosingAttach = true;
|
||||
base::call_delayed(
|
||||
st::historyAttach.ripple.hideDuration,
|
||||
this,
|
||||
[=] { _choosingAttach = false; chooseAttach(); });
|
||||
[=] { chooseAttach(overrideCompress); });
|
||||
}, lifetime());
|
||||
|
||||
_composeControls->fileChosen(
|
||||
|
@ -814,7 +815,9 @@ void RepliesWidget::setupComposeControls() {
|
|||
}
|
||||
}
|
||||
|
||||
void RepliesWidget::chooseAttach() {
|
||||
void RepliesWidget::chooseAttach(
|
||||
std::optional<bool> overrideSendImagesAsPhotos) {
|
||||
_choosingAttach = false;
|
||||
if (const auto error = Data::RestrictionError(
|
||||
_history->peer,
|
||||
ChatRestriction::SendMedia)) {
|
||||
|
@ -827,7 +830,9 @@ void RepliesWidget::chooseAttach() {
|
|||
return;
|
||||
}
|
||||
|
||||
const auto filter = FileDialog::AllOrImagesFilter();
|
||||
const auto filter = (overrideSendImagesAsPhotos == true)
|
||||
? FileDialog::ImagesOrAllFilter()
|
||||
: FileDialog::AllOrImagesFilter();
|
||||
FileDialog::GetOpenPaths(this, tr::lng_choose_files(tr::now), filter, crl::guard(this, [=](
|
||||
FileDialog::OpenResult &&result) {
|
||||
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
|
||||
|
@ -841,7 +846,8 @@ void RepliesWidget::chooseAttach() {
|
|||
if (!read.image.isNull() && !read.animated) {
|
||||
confirmSendingFiles(
|
||||
std::move(read.image),
|
||||
std::move(result.remoteContent));
|
||||
std::move(result.remoteContent),
|
||||
overrideSendImagesAsPhotos);
|
||||
} else {
|
||||
uploadFile(result.remoteContent, SendMediaType::File);
|
||||
}
|
||||
|
@ -851,6 +857,7 @@ void RepliesWidget::chooseAttach() {
|
|||
result.paths,
|
||||
st::sendMediaPreviewSize,
|
||||
premium);
|
||||
list.overrideSendImagesAsPhotos = overrideSendImagesAsPhotos;
|
||||
confirmSendingFiles(std::move(list));
|
||||
}
|
||||
}), nullptr);
|
||||
|
|
|
@ -230,7 +230,7 @@ private:
|
|||
not_null<HistoryItem*> item,
|
||||
Api::SendOptions options,
|
||||
mtpRequestId *const saveEditMsgRequestId);
|
||||
void chooseAttach();
|
||||
void chooseAttach(std::optional<bool> overrideSendImagesAsPhotos);
|
||||
[[nodiscard]] SendMenu::Type sendMenuType() const;
|
||||
[[nodiscard]] MsgId replyToId() const;
|
||||
[[nodiscard]] HistoryItem *lookupRoot() const;
|
||||
|
|
|
@ -55,6 +55,18 @@ struct ParsedBot {
|
|||
bool inactive = false;
|
||||
};
|
||||
|
||||
[[nodiscard]] bool IsSame(
|
||||
const std::optional<Api::SendAction> &a,
|
||||
const Api::SendAction &b) {
|
||||
// Check fields that are sent to API in bot attach webview requests.
|
||||
return a.has_value()
|
||||
&& (a->history == b.history)
|
||||
&& (a->replyTo == b.replyTo)
|
||||
&& (a->topicRootId == b.topicRootId)
|
||||
&& (a->options.sendAs == b.options.sendAs)
|
||||
&& (a->options.silent == b.options.silent);
|
||||
}
|
||||
|
||||
[[nodiscard]] DocumentData *ResolveIcon(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPDattachMenuBot &data) {
|
||||
|
@ -400,14 +412,14 @@ AttachWebView::~AttachWebView() {
|
|||
}
|
||||
|
||||
void AttachWebView::request(
|
||||
not_null<PeerData*> peer,
|
||||
const Api::SendAction &action,
|
||||
const QString &botUsername,
|
||||
const QString &startCommand) {
|
||||
if (botUsername.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
const auto username = _bot ? _bot->username() : _botUsername;
|
||||
if (_peer == peer
|
||||
if (IsSame(_action, action)
|
||||
&& username.toLower() == botUsername.toLower()
|
||||
&& _startCommand == startCommand) {
|
||||
if (_panel) {
|
||||
|
@ -417,7 +429,7 @@ void AttachWebView::request(
|
|||
}
|
||||
cancel();
|
||||
|
||||
_peer = peer;
|
||||
_action = action;
|
||||
_botUsername = botUsername;
|
||||
_startCommand = startCommand;
|
||||
resolve();
|
||||
|
@ -425,10 +437,10 @@ void AttachWebView::request(
|
|||
|
||||
void AttachWebView::request(
|
||||
Window::SessionController *controller,
|
||||
not_null<PeerData*> peer,
|
||||
const Api::SendAction &action,
|
||||
not_null<UserData*> bot,
|
||||
const WebViewButton &button) {
|
||||
if (_peer == peer && _bot == bot) {
|
||||
if (IsSame(_action, action) && _bot == bot) {
|
||||
if (_panel) {
|
||||
_panel->requestActivate();
|
||||
} else if (_requestId) {
|
||||
|
@ -438,7 +450,7 @@ void AttachWebView::request(
|
|||
cancel();
|
||||
|
||||
_bot = bot;
|
||||
_peer = peer;
|
||||
_action = action;
|
||||
if (controller) {
|
||||
confirmOpen(controller, [=] {
|
||||
request(button);
|
||||
|
@ -449,24 +461,31 @@ void AttachWebView::request(
|
|||
}
|
||||
|
||||
void AttachWebView::request(const WebViewButton &button) {
|
||||
Expects(_peer != nullptr && _bot != nullptr);
|
||||
Expects(_action.has_value() && _bot != nullptr);
|
||||
|
||||
_startCommand = button.startCommand;
|
||||
|
||||
using Flag = MTPmessages_RequestWebView::Flag;
|
||||
const auto flags = Flag::f_theme_params
|
||||
| (button.url.isEmpty() ? Flag(0) : Flag::f_url)
|
||||
| (_startCommand.isEmpty() ? Flag(0) : Flag::f_start_param);
|
||||
| (_startCommand.isEmpty() ? Flag(0) : Flag::f_start_param)
|
||||
| (_action->replyTo ? Flag::f_reply_to_msg_id : Flag(0))
|
||||
| (_action->topicRootId ? Flag::f_top_msg_id : Flag(0))
|
||||
| (_action->options.sendAs ? Flag::f_send_as : Flag(0))
|
||||
| (_action->options.silent ? Flag::f_silent : Flag(0));
|
||||
_requestId = _session->api().request(MTPmessages_RequestWebView(
|
||||
MTP_flags(flags),
|
||||
_peer->input,
|
||||
_action->history->peer->input,
|
||||
_bot->inputUser,
|
||||
MTP_bytes(button.url),
|
||||
MTP_string(_startCommand),
|
||||
MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json)),
|
||||
MTP_string("tdesktop"),
|
||||
MTPint(), // reply_to_msg_id
|
||||
MTPInputPeer() // send_as
|
||||
MTP_int(_action->replyTo.bare),
|
||||
MTP_int(_action->topicRootId.bare),
|
||||
(_action->options.sendAs
|
||||
? _action->options.sendAs->input
|
||||
: MTP_inputPeerEmpty())
|
||||
)).done([=](const MTPWebViewResult &result) {
|
||||
_requestId = 0;
|
||||
result.match([&](const MTPDwebViewResultUrl &data) {
|
||||
|
@ -485,7 +504,8 @@ void AttachWebView::cancel() {
|
|||
_session->api().request(base::take(_requestId)).cancel();
|
||||
_session->api().request(base::take(_prolongId)).cancel();
|
||||
_panel = nullptr;
|
||||
_peer = _bot = nullptr;
|
||||
_action = std::nullopt;
|
||||
_bot = nullptr;
|
||||
_botUsername = QString();
|
||||
_startCommand = QString();
|
||||
}
|
||||
|
@ -523,7 +543,7 @@ void AttachWebView::requestBots() {
|
|||
}
|
||||
|
||||
void AttachWebView::requestAddToMenu(
|
||||
PeerData *peer,
|
||||
const std::optional<Api::SendAction> &action,
|
||||
not_null<UserData*> bot,
|
||||
const QString &startCommand,
|
||||
Window::SessionController *controller,
|
||||
|
@ -537,7 +557,7 @@ void AttachWebView::requestAddToMenu(
|
|||
_addToMenuChooseController = base::make_weak(controller);
|
||||
_addToMenuStartCommand = startCommand;
|
||||
_addToMenuChooseTypes = chooseTypes;
|
||||
_addToMenuPeer = peer;
|
||||
_addToMenuAction = action;
|
||||
if (_addToMenuId) {
|
||||
if (_addToMenuBot == bot) {
|
||||
return;
|
||||
|
@ -550,7 +570,7 @@ void AttachWebView::requestAddToMenu(
|
|||
)).done([=](const MTPAttachMenuBotsBot &result) {
|
||||
_addToMenuId = 0;
|
||||
const auto bot = base::take(_addToMenuBot);
|
||||
const auto contextPeer = base::take(_addToMenuPeer);
|
||||
const auto contextAction = base::take(_addToMenuAction);
|
||||
const auto chooseTypes = base::take(_addToMenuChooseTypes);
|
||||
const auto startCommand = base::take(_addToMenuStartCommand);
|
||||
const auto chooseController = base::take(_addToMenuChooseController);
|
||||
|
@ -558,22 +578,23 @@ void AttachWebView::requestAddToMenu(
|
|||
if (const auto useTypes = chooseTypes & types) {
|
||||
if (const auto strong = chooseController.get()) {
|
||||
const auto callback = [=](not_null<PeerData*> peer) {
|
||||
strong->showPeerHistory(peer);
|
||||
const auto history = peer->owner().history(peer);
|
||||
strong->showPeerHistory(history);
|
||||
request(
|
||||
nullptr,
|
||||
peer,
|
||||
Api::SendAction(history),
|
||||
bot,
|
||||
{ .startCommand = startCommand });
|
||||
};
|
||||
ShowChooseBox(strong, useTypes, callback);
|
||||
}
|
||||
return true;
|
||||
} else if (!contextPeer) {
|
||||
} else if (!contextAction) {
|
||||
return false;
|
||||
}
|
||||
request(
|
||||
nullptr,
|
||||
contextPeer,
|
||||
*contextAction,
|
||||
bot,
|
||||
{ .startCommand = startCommand });
|
||||
return true;
|
||||
|
@ -602,7 +623,7 @@ void AttachWebView::requestAddToMenu(
|
|||
}).fail([=] {
|
||||
_addToMenuId = 0;
|
||||
_addToMenuBot = nullptr;
|
||||
_addToMenuPeer = nullptr;
|
||||
_addToMenuAction = std::nullopt;
|
||||
_addToMenuStartCommand = QString();
|
||||
Ui::ShowMultilineToast({
|
||||
.text = { tr::lng_bot_menu_not_supported(tr::now) },
|
||||
|
@ -627,14 +648,14 @@ void AttachWebView::resolve() {
|
|||
});
|
||||
return;
|
||||
}
|
||||
requestAddToMenu(_peer, _bot, _startCommand);
|
||||
requestAddToMenu(_action, _bot, _startCommand);
|
||||
});
|
||||
}
|
||||
|
||||
void AttachWebView::resolveUsername(
|
||||
const QString &username,
|
||||
Fn<void(not_null<PeerData*>)> done) {
|
||||
if (const auto peer = _peer->owner().peerByUsername(username)) {
|
||||
if (const auto peer = _session->data().peerByUsername(username)) {
|
||||
done(peer);
|
||||
return;
|
||||
}
|
||||
|
@ -644,10 +665,10 @@ void AttachWebView::resolveUsername(
|
|||
)).done([=](const MTPcontacts_ResolvedPeer &result) {
|
||||
_requestId = 0;
|
||||
result.match([&](const MTPDcontacts_resolvedPeer &data) {
|
||||
_peer->owner().processUsers(data.vusers());
|
||||
_peer->owner().processChats(data.vchats());
|
||||
_session->data().processUsers(data.vusers());
|
||||
_session->data().processChats(data.vchats());
|
||||
if (const auto peerId = peerFromMTP(data.vpeer())) {
|
||||
done(_peer->owner().peer(peerId));
|
||||
done(_session->data().peer(peerId));
|
||||
}
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
|
@ -668,7 +689,7 @@ void AttachWebView::requestSimple(
|
|||
const WebViewButton &button) {
|
||||
cancel();
|
||||
_bot = bot;
|
||||
_peer = bot;
|
||||
_action = Api::SendAction(bot->owner().history(bot));
|
||||
confirmOpen(controller, [=] {
|
||||
requestSimple(button);
|
||||
});
|
||||
|
@ -698,7 +719,7 @@ void AttachWebView::requestMenu(
|
|||
not_null<UserData*> bot) {
|
||||
cancel();
|
||||
_bot = bot;
|
||||
_peer = bot;
|
||||
_action = Api::SendAction(bot->owner().history(bot));
|
||||
const auto url = bot->botInfo->botMenuButtonUrl;
|
||||
const auto text = bot->botInfo->botMenuButtonText;
|
||||
confirmOpen(controller, [=] {
|
||||
|
@ -706,15 +727,22 @@ void AttachWebView::requestMenu(
|
|||
_requestId = _session->api().request(MTPmessages_RequestWebView(
|
||||
MTP_flags(Flag::f_theme_params
|
||||
| Flag::f_url
|
||||
| Flag::f_from_bot_menu),
|
||||
_bot->input,
|
||||
| Flag::f_from_bot_menu
|
||||
| (_action->replyTo? Flag::f_reply_to_msg_id : Flag(0))
|
||||
| (_action->topicRootId ? Flag::f_top_msg_id : Flag(0))
|
||||
| (_action->options.sendAs ? Flag::f_send_as : Flag(0))
|
||||
| (_action->options.silent ? Flag::f_silent : Flag(0))),
|
||||
_action->history->peer->input,
|
||||
_bot->inputUser,
|
||||
MTP_string(url),
|
||||
MTPstring(), // url
|
||||
MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json)),
|
||||
MTP_string("tdesktop"),
|
||||
MTPint(), // reply_to_msg_id
|
||||
MTPInputPeer() // send_as
|
||||
MTP_int(_action->replyTo.bare),
|
||||
MTP_int(_action->topicRootId.bare),
|
||||
(_action->options.sendAs
|
||||
? _action->options.sendAs->input
|
||||
: MTP_inputPeerEmpty())
|
||||
)).done([=](const MTPWebViewResult &result) {
|
||||
_requestId = 0;
|
||||
result.match([&](const MTPDwebViewResultUrl &data) {
|
||||
|
@ -765,13 +793,13 @@ void AttachWebView::show(
|
|||
uint64 queryId,
|
||||
const QString &url,
|
||||
const QString &buttonText) {
|
||||
Expects(_bot != nullptr && _peer != nullptr);
|
||||
Expects(_bot != nullptr && _action.has_value());
|
||||
|
||||
const auto close = crl::guard(this, [=] {
|
||||
crl::on_main(this, [=] { cancel(); });
|
||||
});
|
||||
const auto sendData = crl::guard(this, [=](QByteArray data) {
|
||||
if (_peer != _bot || queryId) {
|
||||
if (!_action || _action->history->peer != _bot || queryId) {
|
||||
return;
|
||||
}
|
||||
const auto randomId = base::RandomValue<uint64>();
|
||||
|
@ -832,7 +860,7 @@ void AttachWebView::show(
|
|||
const auto hasSettings = (attached != end(_attachBots))
|
||||
&& !attached->inactive
|
||||
&& attached->hasSettings;
|
||||
const auto hasOpenBot = (_bot != _peer);
|
||||
const auto hasOpenBot = !_action || (_bot != _action->history->peer);
|
||||
const auto hasRemoveFromMenu = (attached != end(_attachBots))
|
||||
&& !attached->inactive;
|
||||
const auto buttons = (hasSettings ? Button::Settings : Button::None)
|
||||
|
@ -894,7 +922,7 @@ void AttachWebView::show(
|
|||
}
|
||||
|
||||
void AttachWebView::started(uint64 queryId) {
|
||||
Expects(_peer != nullptr && _bot != nullptr);
|
||||
Expects(_action.has_value() && _bot != nullptr);
|
||||
|
||||
_session->data().webViewResultSent(
|
||||
) | rpl::filter([=](const Data::Session::WebViewResultSent &sent) {
|
||||
|
@ -907,15 +935,21 @@ void AttachWebView::started(uint64 queryId) {
|
|||
kProlongTimeout
|
||||
) | rpl::start_with_next([=] {
|
||||
using Flag = MTPmessages_ProlongWebView::Flag;
|
||||
auto flags = Flag::f_reply_to_msg_id | Flag::f_silent;
|
||||
_session->api().request(base::take(_prolongId)).cancel();
|
||||
_prolongId = _session->api().request(MTPmessages_ProlongWebView(
|
||||
MTP_flags(flags),
|
||||
_peer->input,
|
||||
MTP_flags(Flag(0)
|
||||
| (_action->replyTo ? Flag::f_reply_to_msg_id : Flag(0))
|
||||
| (_action->topicRootId ? Flag::f_top_msg_id : Flag(0))
|
||||
| (_action->options.sendAs ? Flag::f_send_as : Flag(0))
|
||||
| (_action->options.silent ? Flag::f_silent : Flag(0))),
|
||||
_action->history->peer->input,
|
||||
_bot->inputUser,
|
||||
MTP_long(queryId),
|
||||
MTP_int(_replyToMsgId.bare),
|
||||
MTPInputPeer() // send_as
|
||||
MTP_int(_action->replyTo.bare),
|
||||
MTP_int(_action->topicRootId.bare),
|
||||
(_action->options.sendAs
|
||||
? _action->options.sendAs->input
|
||||
: MTP_inputPeerEmpty())
|
||||
)).done([=] {
|
||||
_prolongId = 0;
|
||||
}).send();
|
||||
|
@ -971,6 +1005,7 @@ void AttachWebView::toggleInMenu(
|
|||
std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<PeerData*> peer,
|
||||
Fn<Api::SendAction()> actionFactory,
|
||||
Fn<void(bool)> attach) {
|
||||
auto result = std::make_unique<Ui::DropdownMenu>(
|
||||
parent,
|
||||
|
@ -991,7 +1026,7 @@ std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
|
|||
raw,
|
||||
raw->menu()->st(),
|
||||
bot,
|
||||
[=] { bots->request(nullptr, peer, bot.user, {}); });
|
||||
[=] { bots->request(nullptr, actionFactory(), bot.user, {}); });
|
||||
action->forceShown(
|
||||
) | rpl::start_with_next([=](bool shown) {
|
||||
if (shown) {
|
||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "api/api_common.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "base/weak_ptr.h"
|
||||
#include "base/flags.h"
|
||||
|
@ -70,12 +71,12 @@ public:
|
|||
QByteArray url;
|
||||
};
|
||||
void request(
|
||||
not_null<PeerData*> peer,
|
||||
const Api::SendAction &action,
|
||||
const QString &botUsername,
|
||||
const QString &startCommand);
|
||||
void request(
|
||||
Window::SessionController *controller,
|
||||
not_null<PeerData*> peer,
|
||||
const Api::SendAction &action,
|
||||
not_null<UserData*> bot,
|
||||
const WebViewButton &button);
|
||||
void requestSimple(
|
||||
|
@ -97,7 +98,7 @@ public:
|
|||
}
|
||||
|
||||
void requestAddToMenu(
|
||||
PeerData *peer,
|
||||
const std::optional<Api::SendAction> &action,
|
||||
not_null<UserData*> bot,
|
||||
const QString &startCommand,
|
||||
Window::SessionController *controller = nullptr,
|
||||
|
@ -134,12 +135,11 @@ private:
|
|||
|
||||
const not_null<Main::Session*> _session;
|
||||
|
||||
PeerData *_peer = nullptr;
|
||||
std::optional<Api::SendAction> _action;
|
||||
UserData *_bot = nullptr;
|
||||
QString _botUsername;
|
||||
QString _startCommand;
|
||||
QPointer<Ui::GenericBox> _confirmAddBox;
|
||||
MsgId _replyToMsgId;
|
||||
|
||||
mtpRequestId _requestId = 0;
|
||||
mtpRequestId _prolongId = 0;
|
||||
|
@ -147,7 +147,7 @@ private:
|
|||
uint64 _botsHash = 0;
|
||||
mtpRequestId _botsRequestId = 0;
|
||||
|
||||
PeerData *_addToMenuPeer = nullptr;
|
||||
std::optional<Api::SendAction> _addToMenuAction;
|
||||
UserData *_addToMenuBot = nullptr;
|
||||
mtpRequestId _addToMenuId = 0;
|
||||
QString _addToMenuStartCommand;
|
||||
|
@ -164,6 +164,7 @@ private:
|
|||
[[nodiscard]] std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<PeerData*> peer,
|
||||
Fn<Api::SendAction()> actionFactory,
|
||||
Fn<void(bool)> attach);
|
||||
|
||||
} // namespace InlineBots
|
||||
|
|
|
@ -394,9 +394,10 @@ void SessionNavigation::showPeerByLinkResolved(
|
|||
}
|
||||
if (!attachBotUsername.isEmpty()) {
|
||||
crl::on_main(this, [=] {
|
||||
showPeerHistory(peer->id, params, msgId);
|
||||
const auto history = peer->owner().history(peer);
|
||||
showPeerHistory(history, params, msgId);
|
||||
peer->session().attachWebView().request(
|
||||
peer,
|
||||
Api::SendAction(history),
|
||||
attachBotUsername,
|
||||
info.attachBotToggleCommand.value_or(QString()));
|
||||
});
|
||||
|
@ -410,7 +411,10 @@ void SessionNavigation::showPeerByLinkResolved(
|
|||
? contextPeer->asUser()
|
||||
: nullptr;
|
||||
bot->session().attachWebView().requestAddToMenu(
|
||||
contextUser,
|
||||
(contextUser
|
||||
? Api::SendAction(
|
||||
contextUser->owner().history(contextUser))
|
||||
: std::optional<Api::SendAction>()),
|
||||
bot,
|
||||
*info.attachBotToggleCommand,
|
||||
parentController(),
|
||||
|
|
Loading…
Add table
Reference in a new issue