Show terms on attach bot direct link app.

This commit is contained in:
John Preston 2023-09-12 10:03:51 +04:00
parent ef969df86e
commit 36f1a18b3b
4 changed files with 99 additions and 47 deletions

View File

@ -904,23 +904,28 @@ void AttachWebView::requestBots() {
}).send();
}
bool AttachWebView::showingDisclaimer(const AttachWebViewBot &bot) const {
return bot.disclaimerRequired
&& !_disclaimerAccepted.contains(bot.user);
bool AttachWebView::disclaimerAccepted(const AttachWebViewBot &bot) const {
return _disclaimerAccepted.contains(bot.user);
}
bool AttachWebView::showMainMenuNewBadge(
const AttachWebViewBot &bot) const {
return bot.inMainMenu
&& bot.disclaimerRequired
&& !disclaimerAccepted(bot);
}
void AttachWebView::requestAddToMenu(
not_null<UserData*> bot,
std::optional<QString> startCommand) {
requestAddToMenu(bot, startCommand, nullptr, std::nullopt, PeerTypes());
AddToMenuOpen open) {
requestAddToMenu(bot, open, nullptr, std::nullopt);
}
void AttachWebView::requestAddToMenu(
not_null<UserData*> bot,
std::optional<QString> startCommand,
AddToMenuOpen open,
Window::SessionController *controller,
std::optional<Api::SendAction> action,
PeerTypes chooseTypes) {
std::optional<Api::SendAction> action) {
Expects(controller != nullptr || _context != nullptr);
if (!bot->isBot() || !bot->botInfo->supportsAttachMenu) {
@ -929,8 +934,7 @@ void AttachWebView::requestAddToMenu(
}
const auto wasController = (controller != nullptr);
_addToMenuChooseController = base::make_weak(controller);
_addToMenuStartCommand = startCommand;
_addToMenuChooseTypes = chooseTypes;
_addToMenuOpen = open;
if (!controller) {
_addToMenuContext = base::take(_context);
} else if (action) {
@ -950,17 +954,30 @@ void AttachWebView::requestAddToMenu(
_addToMenuId = 0;
const auto bot = base::take(_addToMenuBot);
const auto context = std::shared_ptr(base::take(_addToMenuContext));
const auto chooseTypes = base::take(_addToMenuChooseTypes);
const auto startCommand = base::take(_addToMenuStartCommand);
const auto open = base::take(_addToMenuOpen);
const auto chooseController = base::take(_addToMenuChooseController);
const auto open = [=](PeerTypes types) {
const auto launch = [=](PeerTypes types) {
const auto openAttach = v::is<AddToMenuOpenAttach>(open)
? v::get<AddToMenuOpenAttach>(open)
: AddToMenuOpenAttach();
const auto chooseTypes = openAttach.chooseTypes;
const auto strong = chooseController.get();
if (!strong) {
if (wasController || !startCommand) {
if (v::is<AddToMenuOpenApp>(open)) {
if (!context) {
return false;
}
const auto &openApp = v::get<AddToMenuOpenApp>(open);
_app = openApp.app;
_startCommand = openApp.startCommand;
_context = std::make_unique<Context>(*context);
requestAppView(true);
return true;
} else if (!strong) {
if (wasController || !v::is<AddToMenuOpenAttach>(open)) {
// Just ignore the click if controller was destroyed.
return true;
}
} else if (!startCommand) {
} else if (v::is<AddToMenuOpenMenu>(open)) {
_bot = bot;
requestSimple(strong, bot, { .fromMainMenu = true });
return true;
@ -969,7 +986,7 @@ void AttachWebView::requestAddToMenu(
strong->showThread(thread);
requestWithOptionalConfirm(
bot,
{ .startCommand = *startCommand },
{ .startCommand = openAttach.startCommand },
LookupContext(strong, Api::SendAction(thread)));
};
ShowChooseBox(strong, useTypes, done);
@ -980,7 +997,7 @@ void AttachWebView::requestAddToMenu(
}
requestWithOptionalConfirm(
bot,
{ .startCommand = *startCommand },
{ .startCommand = openAttach.startCommand },
*context);
return true;
};
@ -999,11 +1016,11 @@ void AttachWebView::requestAddToMenu(
const auto types = parsed->types;
if (parsed->inactive) {
confirmAddToMenu(*parsed, [=] {
open(types);
launch(types);
});
} else {
requestBots();
if (!open(types)) {
if (!launch(types)) {
showToast(
tr::lng_bot_menu_already_added(tr::now));
}
@ -1014,9 +1031,20 @@ void AttachWebView::requestAddToMenu(
}).fail([=] {
_addToMenuId = 0;
_addToMenuBot = nullptr;
_addToMenuContext = nullptr;
_addToMenuStartCommand = std::nullopt;
showToast(tr::lng_bot_menu_not_supported(tr::now));
auto context = base::take(_addToMenuContext);
const auto open = base::take(_addToMenuOpen);
if (const auto openApp = std::get_if<AddToMenuOpenApp>(&open)) {
_app = openApp->app;
_startCommand = openApp->startCommand;
_context = std::move(context);
if (_appConfirmationRequired) {
confirmAppOpen(_appRequestWriteAccess);
} else {
requestAppView(false);
}
} else {
showToast(tr::lng_bot_menu_not_supported(tr::now));
}
}).send();
}
@ -1046,7 +1074,9 @@ void AttachWebView::resolve() {
showToast(tr::lng_bot_menu_not_supported(tr::now));
return;
}
requestAddToMenu(_bot, _startCommand);
requestAddToMenu(_bot, AddToMenuOpenAttach{
.startCommand = _startCommand,
});
});
}
@ -1209,12 +1239,14 @@ void AttachWebView::requestApp(
showToast(tr::lng_username_app_not_found(tr::now));
return;
}
const auto confirm = firstTime || forceConfirmation;
if (confirm) {
confirmAppOpen(result.data().is_request_write_access());
} else {
requestAppView(false);
}
// Check if this app can be added to main menu.
// On fail it'll still be opened.
_appConfirmationRequired = firstTime || forceConfirmation;
_appRequestWriteAccess = result.data().is_request_write_access();
requestAddToMenu(_bot, AddToMenuOpenApp{
.app = _app,
.startCommand = _startCommand,
});
}).fail([=] {
showToast(tr::lng_username_app_not_found(tr::now));
cancel();
@ -1331,9 +1363,9 @@ void AttachWebView::acceptDisclaimer(
_attachBotsUpdates.fire({});
return;
} else if (i->inactive) {
requestAddToMenu(_bot, {}, controller, {}, {});
requestAddToMenu(_bot, AddToMenuOpenMenu(), controller, {});
return;
} else if (!showingDisclaimer(*i)) {
} else if (!i->disclaimerRequired || disclaimerAccepted(*i)) {
done();
return;
}
@ -1478,7 +1510,7 @@ void AttachWebView::confirmAddToMenu(
});
close();
};
const auto disclaimer = showingDisclaimer(bot);
const auto disclaimer = !disclaimerAccepted(bot);
if (disclaimer) {
FillDisclaimerBox(box, [=] {
_disclaimerAccepted.emplace(bot.user);

View File

@ -70,6 +70,21 @@ struct AttachWebViewBot {
bool requestWriteAccess : 1 = false;
};
struct AddToMenuOpenAttach {
QString startCommand;
PeerTypes chooseTypes;
};
struct AddToMenuOpenMenu {
};
struct AddToMenuOpenApp {
not_null<BotAppData*> app;
QString startCommand;
};
using AddToMenuOpen = std::variant<
AddToMenuOpenAttach,
AddToMenuOpenMenu,
AddToMenuOpenApp>;
class AttachWebView final
: public base::has_weak_ptr
, public Ui::BotWebView::Delegate {
@ -119,17 +134,19 @@ public:
[[nodiscard]] rpl::producer<> attachBotsUpdates() const {
return _attachBotsUpdates.events();
}
[[nodiscard]] bool showingDisclaimer(const AttachWebViewBot &bot) const;
[[nodiscard]] bool disclaimerAccepted(
const AttachWebViewBot &bot) const;
[[nodiscard]] bool showMainMenuNewBadge(
const AttachWebViewBot &bot) const;
void requestAddToMenu(
not_null<UserData*> bot,
std::optional<QString> startCommand);
AddToMenuOpen open);
void requestAddToMenu(
not_null<UserData*> bot,
std::optional<QString> startCommand,
AddToMenuOpen open,
Window::SessionController *controller,
std::optional<Api::SendAction> action,
PeerTypes chooseTypes);
std::optional<Api::SendAction> action);
void removeFromMenu(not_null<UserData*> bot);
[[nodiscard]] std::optional<Api::SendAction> lookupLastAction(
@ -140,6 +157,7 @@ public:
private:
struct Context;
Webview::ThemeParams botThemeParams() override;
bool botHandleLocalUri(QString uri) override;
void botHandleInvoice(QString slug) override;
@ -224,6 +242,8 @@ private:
QString _startCommand;
BotAppData *_app = nullptr;
QPointer<Ui::GenericBox> _confirmAddBox;
bool _appConfirmationRequired = false;
bool _appRequestWriteAccess = false;
mtpRequestId _requestId = 0;
mtpRequestId _prolongId = 0;
@ -234,9 +254,8 @@ private:
std::unique_ptr<Context> _addToMenuContext;
UserData *_addToMenuBot = nullptr;
mtpRequestId _addToMenuId = 0;
std::optional<QString> _addToMenuStartCommand;
AddToMenuOpen _addToMenuOpen;
base::weak_ptr<Window::SessionController> _addToMenuChooseController;
PeerTypes _addToMenuChooseTypes;
std::vector<AttachWebViewBot> _attachBots;
rpl::event_stream<> _attachBotsUpdates;

View File

@ -254,7 +254,7 @@ void SetupMenuBots(
}
}, button->lifetime());
const auto badge = bots->showingDisclaimer(bot)
const auto badge = bots->showMainMenuNewBadge(bot)
? Ui::CreateChild<Ui::PaddingWrap<Ui::FlatLabel>>(
button.get(),
object_ptr<Ui::FlatLabel>(

View File

@ -589,20 +589,21 @@ void SessionNavigation::showPeerByLinkResolved(
: nullptr;
bot->session().attachWebView().requestAddToMenu(
bot,
*info.attachBotToggleCommand,
InlineBots::AddToMenuOpenAttach{
.startCommand = *info.attachBotToggleCommand,
.chooseTypes = info.attachBotChooseTypes,
},
parentController(),
(contextUser
? Api::SendAction(
contextUser->owner().history(contextUser))
: std::optional<Api::SendAction>()),
info.attachBotChooseTypes);
: std::optional<Api::SendAction>()));
} else if (bot && info.attachBotMenuOpen) {
bot->session().attachWebView().requestAddToMenu(
bot,
std::nullopt,
InlineBots::AddToMenuOpenMenu(),
parentController(),
std::optional<Api::SendAction>(),
{});
std::optional<Api::SendAction>());
} else {
crl::on_main(this, [=] {
showPeerHistory(peer, params, msgId);