mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-01 12:00:48 +00:00
Add bot menu button with webview open support.
This commit is contained in:
parent
d35b8f82a3
commit
94c6793e92
@ -1755,6 +1755,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_bot_add_to_menu_done" = "Bot added to the menu.";
|
||||
"lng_bot_menu_not_supported" = "This bot isn't supported in the attach menu.";
|
||||
"lng_bot_menu_already_added" = "This bot is already added in your attach menu.";
|
||||
"lng_bot_menu_button" = "Menu";
|
||||
|
||||
"lng_typing" = "typing";
|
||||
"lng_user_typing" = "{user} is typing";
|
||||
|
@ -133,10 +133,23 @@ void UserData::setBotInfo(const MTPBotInfo &info) {
|
||||
const auto changedCommands = Data::UpdateBotCommands(
|
||||
botInfo->commands,
|
||||
d.vcommands());
|
||||
auto text = QString();
|
||||
auto url = QString();
|
||||
d.vmenu_button().match([&](const MTPDbotMenuButton &data) {
|
||||
text = qs(data.vtext());
|
||||
url = qs(data.vurl());
|
||||
}, [&](const auto &) {
|
||||
});
|
||||
const auto changedButton = (botInfo->botMenuButtonText != text)
|
||||
|| (botInfo->botMenuButtonUrl != url);
|
||||
if (changedButton) {
|
||||
botInfo->botMenuButtonText = text;
|
||||
botInfo->botMenuButtonUrl = url;
|
||||
}
|
||||
|
||||
botInfo->inited = true;
|
||||
|
||||
if (changedCommands) {
|
||||
if (changedCommands || changedButton) {
|
||||
owner().botCommandsChanged(this);
|
||||
}
|
||||
} break;
|
||||
|
@ -612,6 +612,10 @@ HistoryWidget::HistoryWidget(
|
||||
) | rpl::filter([=](not_null<PeerData*> peer) {
|
||||
return _peer && (_peer == peer);
|
||||
}) | rpl::start_with_next([=] {
|
||||
if (updateCmdStartShown()) {
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
}
|
||||
if (_fieldAutocomplete->clearFilteredBotCommands()) {
|
||||
checkFieldAutocomplete();
|
||||
}
|
||||
@ -2701,6 +2705,9 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
_botKeyboardShow->hide();
|
||||
_botKeyboardHide->hide();
|
||||
_botCommandStart->hide();
|
||||
if (_botMenuButton) {
|
||||
_botMenuButton->hide();
|
||||
}
|
||||
if (_tabbedPanel) {
|
||||
_tabbedPanel->hide();
|
||||
}
|
||||
@ -2751,6 +2758,9 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
}
|
||||
}
|
||||
_attachToggle->show();
|
||||
if (_botMenuButton) {
|
||||
_botMenuButton->show();
|
||||
}
|
||||
if (_silent) {
|
||||
_silent->show();
|
||||
}
|
||||
@ -2798,6 +2808,9 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
if (_sendAs) {
|
||||
_sendAs->hide();
|
||||
}
|
||||
if (_botMenuButton) {
|
||||
_botMenuButton->hide();
|
||||
}
|
||||
_kbScroll->hide();
|
||||
_fieldBarCancel->hide();
|
||||
_tabbedSelectorToggle->hide();
|
||||
@ -4427,19 +4440,66 @@ void HistoryWidget::updateSendButtonType() {
|
||||
}
|
||||
|
||||
bool HistoryWidget::updateCmdStartShown() {
|
||||
const auto bot = (_peer && _peer->asUser()->isBot())
|
||||
? _peer->asUser()
|
||||
: nullptr;
|
||||
bool cmdStartShown = false;
|
||||
if (_history && _peer && ((_peer->isChat() && _peer->asChat()->botStatus > 0) || (_peer->isMegagroup() && _peer->asChannel()->mgInfo->botStatus > 0) || (_peer->isUser() && _peer->asUser()->isBot()))) {
|
||||
if (_history && _peer && ((_peer->isChat() && _peer->asChat()->botStatus > 0) || (_peer->isMegagroup() && _peer->asChannel()->mgInfo->botStatus > 0))) {
|
||||
if (!isBotStart() && !isBlocked() && !_keyboard->hasMarkup() && !_keyboard->forceReply() && !_editMsgId) {
|
||||
if (!HasSendText(_field)) {
|
||||
cmdStartShown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_cmdStartShown != cmdStartShown) {
|
||||
_cmdStartShown = cmdStartShown;
|
||||
return true;
|
||||
const auto commandsChanged = (_cmdStartShown != cmdStartShown);
|
||||
auto buttonChanged = false;
|
||||
if (!bot
|
||||
|| (bot->botInfo->botMenuButtonUrl.isEmpty()
|
||||
&& bot->botInfo->commands.empty())) {
|
||||
buttonChanged = (_botMenuButton != nullptr);
|
||||
_botMenuButton.destroy();
|
||||
} else if (!_botMenuButton) {
|
||||
buttonChanged = true;
|
||||
_botMenuButtonText = bot->botInfo->botMenuButtonText;
|
||||
_botMenuButton.create(
|
||||
this,
|
||||
(_botMenuButtonText.isEmpty()
|
||||
? tr::lng_bot_menu_button()
|
||||
: rpl::single(_botMenuButtonText)),
|
||||
st::historyBotMenuButton);
|
||||
_botMenuButton->setTextTransform(
|
||||
Ui::RoundButton::TextTransform::NoTransform);
|
||||
_botMenuButton->setFullRadius(true);
|
||||
_botMenuButton->setClickedCallback([=] {
|
||||
const auto user = _peer ? _peer->asUser() : nullptr;
|
||||
const auto bot = (user && user->isBot()) ? user : nullptr;
|
||||
if (bot && !bot->botInfo->botMenuButtonUrl.isEmpty()) {
|
||||
session().attachWebView().requestMenu(controller(), bot);
|
||||
} else if (!_fieldAutocomplete->isHidden()) {
|
||||
_fieldAutocomplete->hideAnimated();
|
||||
} else {
|
||||
_fieldAutocomplete->showFiltered(_peer, "/", true);
|
||||
}
|
||||
});
|
||||
_botMenuButton->widthValue(
|
||||
) | rpl::start_with_next([=](int width) {
|
||||
if (width > st::historyBotMenuMaxWidth) {
|
||||
_botMenuButton->setFullWidth(st::historyBotMenuMaxWidth);
|
||||
} else {
|
||||
updateFieldSize();
|
||||
}
|
||||
}, _botMenuButton->lifetime());
|
||||
}
|
||||
return false;
|
||||
const auto textChanged = _botMenuButton
|
||||
&& (_botMenuButtonText != bot->botInfo->botMenuButtonText);
|
||||
if (textChanged) {
|
||||
_botMenuButtonText = bot->botInfo->botMenuButtonText;
|
||||
_botMenuButton->setText(_botMenuButtonText.isEmpty()
|
||||
? tr::lng_bot_menu_button()
|
||||
: rpl::single(_botMenuButtonText));
|
||||
}
|
||||
_cmdStartShown = cmdStartShown;
|
||||
return commandsChanged || buttonChanged || textChanged;
|
||||
}
|
||||
|
||||
void HistoryWidget::searchInChat() {
|
||||
@ -4697,12 +4757,16 @@ void HistoryWidget::moveFieldControls() {
|
||||
_kbScroll->setGeometryToLeft(0, bottom, width(), keyboardHeight);
|
||||
}
|
||||
|
||||
// _attachToggle (_sendAs) ------- _inlineResults ---------------------------------- _tabbedPanel -------- _fieldBarCancel
|
||||
// (_botMenuButton) _attachToggle (_sendAs) ---- _inlineResults ------------------------------ _tabbedPanel ------ _fieldBarCancel
|
||||
// (_attachDocument|_attachPhoto) _field (_ttlInfo) (_scheduled) (_silent|_cmdStart|_kbShow) (_kbHide|_tabbedSelectorToggle) _send
|
||||
// (_botStart|_unblock|_joinChannel|_muteUnmute|_reportMessages)
|
||||
|
||||
auto buttonsBottom = bottom - _attachToggle->height();
|
||||
auto left = st::historySendRight;
|
||||
if (_botMenuButton) {
|
||||
const auto skip = st::historyBotMenuSkip;
|
||||
_botMenuButton->moveToLeft(left + skip, buttonsBottom + skip); left += skip + _botMenuButton->width();
|
||||
}
|
||||
_attachToggle->moveToLeft(left, buttonsBottom); left += _attachToggle->width();
|
||||
if (_sendAs) {
|
||||
_sendAs->moveToLeft(left, buttonsBottom); left += _sendAs->width();
|
||||
@ -4762,6 +4826,7 @@ void HistoryWidget::updateFieldSize() {
|
||||
- st::historySendRight
|
||||
- _send->width()
|
||||
- _tabbedSelectorToggle->width();
|
||||
if (_botMenuButton) fieldWidth -= st::historyBotMenuSkip + _botMenuButton->width();
|
||||
if (_sendAs) fieldWidth -= _sendAs->width();
|
||||
if (kbShowShown) fieldWidth -= _botKeyboardShow->width();
|
||||
if (_cmdStartShown) fieldWidth -= _botCommandStart->width();
|
||||
|
@ -738,6 +738,8 @@ private:
|
||||
object_ptr<Ui::FlatButton> _joinChannel;
|
||||
object_ptr<Ui::FlatButton> _muteUnmute;
|
||||
object_ptr<Ui::FlatButton> _reportMessages;
|
||||
object_ptr<Ui::RoundButton> _botMenuButton = { nullptr };
|
||||
QString _botMenuButtonText;
|
||||
object_ptr<Ui::IconButton> _attachToggle;
|
||||
object_ptr<Ui::SendAsButton> _sendAs = { nullptr };
|
||||
object_ptr<Ui::EmojiButton> _tabbedSelectorToggle;
|
||||
|
@ -572,6 +572,40 @@ void AttachWebView::requestSimple(const WebViewButton &button) {
|
||||
}).send();
|
||||
}
|
||||
|
||||
void AttachWebView::requestMenu(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<UserData*> bot) {
|
||||
cancel();
|
||||
_bot = bot;
|
||||
_peer = bot;
|
||||
const auto url = bot->botInfo->botMenuButtonUrl;
|
||||
const auto text = bot->botInfo->botMenuButtonText;
|
||||
confirmOpen(controller, [=] {
|
||||
using Flag = MTPmessages_RequestWebView::Flag;
|
||||
_requestId = _session->api().request(MTPmessages_RequestWebView(
|
||||
MTP_flags(Flag::f_theme_params
|
||||
| Flag::f_url
|
||||
| Flag::f_from_bot_menu),
|
||||
_bot->input,
|
||||
_bot->inputUser,
|
||||
MTP_string(url),
|
||||
MTPstring(),
|
||||
MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams())),
|
||||
MTPint()
|
||||
)).done([=](const MTPWebViewResult &result) {
|
||||
_requestId = 0;
|
||||
result.match([&](const MTPDwebViewResultUrl &data) {
|
||||
show(data.vquery_id().v, qs(data.vurl()), text);
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_requestId = 0;
|
||||
if (error.type() == u"BOT_INVALID"_q) {
|
||||
requestBots();
|
||||
}
|
||||
}).send();
|
||||
});
|
||||
}
|
||||
|
||||
void AttachWebView::confirmOpen(
|
||||
not_null<Window::SessionController*> controller,
|
||||
Fn<void()> done) {
|
||||
|
@ -64,6 +64,9 @@ public:
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<UserData*> bot,
|
||||
const WebViewButton &button);
|
||||
void requestMenu(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<UserData*> bot);
|
||||
|
||||
void cancel();
|
||||
|
||||
|
@ -167,6 +167,7 @@ void Panel::Button::updateFg(QColor fg) {
|
||||
|
||||
void Panel::Button::updateArgs(MainButtonArgs &&args) {
|
||||
_textFull = std::move(args.text);
|
||||
setDisabled(!args.isActive);
|
||||
setVisible(args.isVisible);
|
||||
toggleProgress(args.isProgressVisible);
|
||||
update();
|
||||
@ -251,8 +252,11 @@ void Panel::Button::paintEvent(QPaintEvent *e) {
|
||||
p,
|
||||
rect().marginsAdded({ 0, st::callRadius * 2, 0, 0 }),
|
||||
RectPart::BottomLeft | RectPart::BottomRight);
|
||||
const auto ripple = ResolveRipple(_bg.color()->c);
|
||||
paintRipple(p, rect().topLeft(), &ripple);
|
||||
|
||||
if (!isDisabled()) {
|
||||
const auto ripple = ResolveRipple(_bg.color()->c);
|
||||
paintRipple(p, rect().topLeft(), &ripple);
|
||||
}
|
||||
|
||||
p.setFont(_st.font);
|
||||
|
||||
@ -646,6 +650,7 @@ void Panel::processMainButtonMessage(const QJsonValue &value) {
|
||||
}
|
||||
|
||||
_mainButton->updateArgs({
|
||||
.isActive = args["is_active"].toBool(),
|
||||
.isVisible = args["is_visible"].toBool(),
|
||||
.isProgressVisible = args["is_progress_visible"].toBool(),
|
||||
.text = args["text"].toString(),
|
||||
@ -659,7 +664,9 @@ void Panel::createMainButton() {
|
||||
const auto button = _mainButton.get();
|
||||
|
||||
button->setClickedCallback([=] {
|
||||
postEvent("main_button_pressed");
|
||||
if (!button->isDisabled()) {
|
||||
postEvent("main_button_pressed");
|
||||
}
|
||||
});
|
||||
button->hide();
|
||||
|
||||
|
@ -22,6 +22,7 @@ struct Available;
|
||||
namespace Ui::BotWebView {
|
||||
|
||||
struct MainButtonArgs {
|
||||
bool isActive = false;
|
||||
bool isVisible = false;
|
||||
bool isProgressVisible = false;
|
||||
QString text;
|
||||
|
@ -239,6 +239,13 @@ historyComposeFieldMaxHeight: 224px;
|
||||
|
||||
historySendPadding: 9px;
|
||||
historySendRight: 2px;
|
||||
historyBotMenuSkip: 8px;
|
||||
historyBotMenuMaxWidth: 160px;
|
||||
historyBotMenuButton: RoundButton(defaultActiveButton) {
|
||||
width: -24px;
|
||||
height: 30px;
|
||||
textTop: 6px;
|
||||
}
|
||||
|
||||
historyComposeButton: FlatButton {
|
||||
color: windowActiveTextFg;
|
||||
|
Loading…
Reference in New Issue
Block a user