mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Support clipboard reading for attach menu bots.
This commit is contained in:
parent
4c181b6d08
commit
c647afec02
4 changed files with 100 additions and 33 deletions
|
@ -490,7 +490,11 @@ void AttachWebView::request(const WebViewButton &button) {
|
|||
)).done([=](const MTPWebViewResult &result) {
|
||||
_requestId = 0;
|
||||
result.match([&](const MTPDwebViewResultUrl &data) {
|
||||
show(data.vquery_id().v, qs(data.vurl()), button.text);
|
||||
show(
|
||||
data.vquery_id().v,
|
||||
qs(data.vurl()),
|
||||
button.text,
|
||||
button.fromMenu);
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_requestId = 0;
|
||||
|
@ -792,7 +796,8 @@ void AttachWebView::ClearAll() {
|
|||
void AttachWebView::show(
|
||||
uint64 queryId,
|
||||
const QString &url,
|
||||
const QString &buttonText) {
|
||||
const QString &buttonText,
|
||||
bool fromMenu) {
|
||||
Expects(_bot != nullptr && _action.has_value());
|
||||
|
||||
const auto close = crl::guard(this, [=] {
|
||||
|
@ -916,6 +921,7 @@ void AttachWebView::show(
|
|||
.menuButtons = buttons,
|
||||
.handleMenuButton = handleMenuButton,
|
||||
.themeParams = [] { return Window::Theme::WebViewParams(); },
|
||||
.allowClipboardRead = fromMenu,
|
||||
});
|
||||
*panel = _panel.get();
|
||||
started(queryId);
|
||||
|
@ -1023,11 +1029,18 @@ std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
|
|||
if (!PeerMatchesTypes(peer, bot.user, bot.types)) {
|
||||
continue;
|
||||
}
|
||||
const auto callback = [=] {
|
||||
bots->request(
|
||||
nullptr,
|
||||
actionFactory(),
|
||||
bot.user,
|
||||
{ .fromMenu = true });
|
||||
};
|
||||
auto action = base::make_unique_q<BotAction>(
|
||||
raw,
|
||||
raw->menu()->st(),
|
||||
bot,
|
||||
[=] { bots->request(nullptr, actionFactory(), bot.user, {}); });
|
||||
callback);
|
||||
action->forceShown(
|
||||
) | rpl::start_with_next([=](bool shown) {
|
||||
if (shown) {
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
QString text;
|
||||
QString startCommand;
|
||||
QByteArray url;
|
||||
bool fromMenu = false;
|
||||
};
|
||||
void request(
|
||||
const Api::SendAction &action,
|
||||
|
@ -127,7 +128,8 @@ private:
|
|||
void show(
|
||||
uint64 queryId,
|
||||
const QString &url,
|
||||
const QString &buttonText = QString());
|
||||
const QString &buttonText = QString(),
|
||||
bool fromMenu = false);
|
||||
void confirmAddToMenu(
|
||||
AttachWebViewBot bot,
|
||||
Fn<void()> callback = nullptr);
|
||||
|
|
|
@ -32,6 +32,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QtCore/QJsonArray>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QClipboard>
|
||||
|
||||
namespace Ui::BotWebView {
|
||||
namespace {
|
||||
|
@ -344,7 +346,8 @@ Panel::Panel(
|
|||
QString phone,
|
||||
MenuButtons menuButtons,
|
||||
Fn<void(MenuButton)> handleMenuButton,
|
||||
Fn<Webview::ThemeParams()> themeParams)
|
||||
Fn<Webview::ThemeParams()> themeParams,
|
||||
bool allowClipboardRead)
|
||||
: _userDataPath(userDataPath)
|
||||
, _handleLocalUri(std::move(handleLocalUri))
|
||||
, _handleInvoice(std::move(handleInvoice))
|
||||
|
@ -353,7 +356,8 @@ Panel::Panel(
|
|||
, _phone(phone)
|
||||
, _menuButtons(menuButtons)
|
||||
, _handleMenuButton(std::move(handleMenuButton))
|
||||
, _widget(std::make_unique<SeparatePanel>()) {
|
||||
, _widget(std::make_unique<SeparatePanel>())
|
||||
, _allowClipboardRead(allowClipboardRead) {
|
||||
_widget->setInnerSize(st::paymentsPanelSize);
|
||||
_widget->setWindowFlag(Qt::WindowStaysOnTopHint, false);
|
||||
|
||||
|
@ -663,6 +667,8 @@ bool Panel::createWebview() {
|
|||
requestPhone();
|
||||
} else if (command == "web_app_setup_closing_behavior") {
|
||||
setupClosingBehaviour(arguments);
|
||||
} else if (command == "web_app_read_text_from_clipboard") {
|
||||
requestClipboardText(arguments);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -737,16 +743,10 @@ void Panel::openExternalLink(const QJsonObject &args) {
|
|||
LOG(("BotWebView Error: Bad 'url' in openExternalLink."));
|
||||
_close();
|
||||
return;
|
||||
} else if (!allowOpenLink()) {
|
||||
return;
|
||||
}
|
||||
const auto now = crl::now();
|
||||
if (_mainButtonLastClick
|
||||
&& _mainButtonLastClick + kProcessClickTimeout >= now) {
|
||||
_mainButtonLastClick = 0;
|
||||
File::OpenUrl(url);
|
||||
} else {
|
||||
const auto string = EncodeForJs(url);
|
||||
_webview->window.eval(("window.open(\"" + string + "\");").toUtf8());
|
||||
}
|
||||
File::OpenUrl(url);
|
||||
}
|
||||
|
||||
void Panel::openInvoice(const QJsonObject &args) {
|
||||
|
@ -816,9 +816,9 @@ void Panel::openPopup(const QJsonObject &args) {
|
|||
QJsonArray{ { QJsonValue(*result.id) } }
|
||||
).toJson(QJsonDocument::Compact) + "[0]";
|
||||
};
|
||||
postEvent(
|
||||
"popup_closed",
|
||||
result.id ? ("\"button_id\": " + safe()) : QString());
|
||||
postEvent("popup_closed", result.id
|
||||
? QJsonObject{ { u"button_id"_q, *result.id } }
|
||||
: EventData());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -841,15 +841,49 @@ void Panel::requestPhone() {
|
|||
},
|
||||
});
|
||||
if (weak) {
|
||||
postEvent(
|
||||
"phone_requested",
|
||||
(result.id == "share"
|
||||
? "\"phone_number\": \"" + _phone + "\""
|
||||
: QString()));
|
||||
postEvent("phone_requested", (result.id == "share")
|
||||
? QJsonObject{ { u"phone_number"_q, _phone } }
|
||||
: EventData());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Panel::requestClipboardText(const QJsonObject &args) {
|
||||
const auto requestId = args["req_id"];
|
||||
if (requestId.isUndefined()) {
|
||||
return;
|
||||
}
|
||||
auto result = QJsonObject();
|
||||
result["req_id"] = requestId;
|
||||
if (allowClipboardQuery()) {
|
||||
result["data"] = QGuiApplication::clipboard()->text();
|
||||
}
|
||||
postEvent(u"clipboard_text_received"_q, result);
|
||||
}
|
||||
|
||||
bool Panel::allowOpenLink() const {
|
||||
const auto now = crl::now();
|
||||
if (_mainButtonLastClick
|
||||
&& _mainButtonLastClick + kProcessClickTimeout >= now) {
|
||||
_mainButtonLastClick = 0;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Panel::allowClipboardQuery() const {
|
||||
if (!_allowClipboardRead) {
|
||||
return false;
|
||||
}
|
||||
const auto now = crl::now();
|
||||
if (_mainButtonLastClick
|
||||
&& _mainButtonLastClick + kProcessClickTimeout >= now) {
|
||||
_mainButtonLastClick = 0;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Panel::scheduleCloseWithConfirmation() {
|
||||
if (!_closeWithConfirmationScheduled) {
|
||||
_closeWithConfirmationScheduled = true;
|
||||
|
@ -1031,16 +1065,17 @@ void Panel::updateThemeParams(const Webview::ThemeParams ¶ms) {
|
|||
params.scrollBgOver,
|
||||
params.scrollBarBg,
|
||||
params.scrollBarBgOver);
|
||||
postEvent("theme_changed", "\"theme_params\": " + params.json);
|
||||
postEvent("theme_changed", "{\"theme_params\": " + params.json + "}");
|
||||
}
|
||||
|
||||
void Panel::invoiceClosed(const QString &slug, const QString &status) {
|
||||
if (!_webview || !_webview->window.widget()) {
|
||||
return;
|
||||
}
|
||||
postEvent(
|
||||
"invoice_closed",
|
||||
"\"slug\": \"" + slug + "\", \"status\": \"" + status + "\"");
|
||||
postEvent("invoice_closed", QJsonObject{
|
||||
{ u"slug"_q, slug },
|
||||
{ u"status"_q, status },
|
||||
});
|
||||
_widget->showAndActivate();
|
||||
_hiddenForPayment = false;
|
||||
}
|
||||
|
@ -1050,13 +1085,21 @@ void Panel::hideForPayment() {
|
|||
_widget->hideGetDuration();
|
||||
}
|
||||
|
||||
void Panel::postEvent(const QString &event, const QString &data) {
|
||||
void Panel::postEvent(const QString &event) {
|
||||
postEvent(event, {});
|
||||
}
|
||||
|
||||
void Panel::postEvent(const QString &event, EventData data) {
|
||||
auto written = v::is<QString>(data)
|
||||
? v::get<QString>(data).toUtf8()
|
||||
: QJsonDocument(
|
||||
v::get<QJsonObject>(data)).toJson(QJsonDocument::Compact);
|
||||
_webview->window.eval(R"(
|
||||
if (window.TelegramGameProxy) {
|
||||
window.TelegramGameProxy.receiveEvent(
|
||||
")"
|
||||
+ event.toUtf8()
|
||||
+ '"' + (data.isEmpty() ? QByteArray() : ", {" + data.toUtf8() + '}')
|
||||
+ '"' + (written.isEmpty() ? QByteArray() : ", " + written)
|
||||
+ R"();
|
||||
}
|
||||
)");
|
||||
|
@ -1110,7 +1153,8 @@ std::unique_ptr<Panel> Show(Args &&args) {
|
|||
args.phone,
|
||||
args.menuButtons,
|
||||
std::move(args.handleMenuButton),
|
||||
std::move(args.themeParams));
|
||||
std::move(args.themeParams),
|
||||
args.allowClipboardRead);
|
||||
if (!result->showWebview(args.url, params, std::move(args.bottom))) {
|
||||
const auto available = Webview::Availability();
|
||||
if (available.error != Webview::Available::Error::None) {
|
||||
|
|
|
@ -52,7 +52,8 @@ public:
|
|||
QString phone,
|
||||
MenuButtons menuButtons,
|
||||
Fn<void(MenuButton)> handleMenuButton,
|
||||
Fn<Webview::ThemeParams()> themeParams);
|
||||
Fn<Webview::ThemeParams()> themeParams,
|
||||
bool allowClipboardRead);
|
||||
~Panel();
|
||||
|
||||
void requestActivate();
|
||||
|
@ -94,13 +95,18 @@ private:
|
|||
void openInvoice(const QJsonObject &args);
|
||||
void openPopup(const QJsonObject &args);
|
||||
void requestPhone();
|
||||
void requestClipboardText(const QJsonObject &args);
|
||||
void setupClosingBehaviour(const QJsonObject &args);
|
||||
void createMainButton();
|
||||
void scheduleCloseWithConfirmation();
|
||||
void closeWithConfirmation();
|
||||
|
||||
void postEvent(const QString &event, const QString &data = {});
|
||||
using EventData = std::variant<QString, QJsonObject>;
|
||||
void postEvent(const QString &event);
|
||||
void postEvent(const QString &event, EventData data);
|
||||
|
||||
[[nodiscard]] bool allowOpenLink() const;
|
||||
[[nodiscard]] bool allowClipboardQuery() const;
|
||||
[[nodiscard]] bool progressWithBackground() const;
|
||||
[[nodiscard]] QRect progressRect() const;
|
||||
void setupProgressGeometry();
|
||||
|
@ -119,7 +125,7 @@ private:
|
|||
std::unique_ptr<RpWidget> _webviewBottom;
|
||||
QPointer<QWidget> _webviewParent;
|
||||
std::unique_ptr<Button> _mainButton;
|
||||
crl::time _mainButtonLastClick = 0;
|
||||
mutable crl::time _mainButtonLastClick = 0;
|
||||
std::unique_ptr<Progress> _progress;
|
||||
rpl::event_stream<> _themeUpdateForced;
|
||||
rpl::lifetime _fgLifetime;
|
||||
|
@ -128,6 +134,7 @@ private:
|
|||
bool _themeUpdateScheduled = false;
|
||||
bool _hiddenForPayment = false;
|
||||
bool _closeWithConfirmationScheduled = false;
|
||||
bool _allowClipboardRead = false;
|
||||
|
||||
};
|
||||
|
||||
|
@ -144,6 +151,7 @@ struct Args {
|
|||
MenuButtons menuButtons;
|
||||
Fn<void(MenuButton)> handleMenuButton;
|
||||
Fn<Webview::ThemeParams()> themeParams;
|
||||
bool allowClipboardRead = false;
|
||||
};
|
||||
[[nodiscard]] std::unique_ptr<Panel> Show(Args &&args);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue