/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "base/expected.h" #include "base/object_ptr.h" #include "base/weak_ptr.h" #include "base/flags.h" #include "ui/platform/ui_platform_utility.h" #include "ui/rect_part.h" #include "ui/widgets/separate_panel.h" #include "webview/webview_common.h" #include #include #include #include #include class QJsonObject; class QJsonValue; namespace Ui { class FlatLabel; class BoxContent; class RpWidget; class StandaloneLayerStack; enum class LayerOption; using LayerOptions = base::flags; } // namespace Ui namespace Webview { struct Available; struct PopupArgs; struct PopupResult; } // namespace Webview namespace Ui::Text { struct MarkedContext; } // namespace Ui::Text namespace Ui::BotWebView::LinuxShell { struct ResolvedColors; } // namespace Ui::BotWebView::LinuxShell namespace Ui::BotWebView { struct DownloadsProgress; struct DownloadsEntry; enum class DownloadsAction; [[nodiscard]] TextWithEntities ErrorText(const Webview::Available &info); enum class MenuButton { None = 0x00, OpenBot = 0x01, RemoveFromMenu = 0x02, RemoveFromMainMenu = 0x04, ShareGame = 0x08, }; inline constexpr bool is_flag_type(MenuButton) { return true; } using MenuButtons = base::flags; using CustomMethodResult = base::expected; struct CustomMethodRequest { QString method; QByteArray params; Fn callback; }; struct SetEmojiStatusRequest { uint64 customEmojiId = 0; TimeId duration = 0; Fn callback; }; struct DownloadFileRequest { QString url; QString name; Fn callback; }; struct ResolveButtonEmojiRequest { uint64 customEmojiId = 0; QColor textColor; int size = 0; Fn callback; }; struct SendPreparedMessageRequest { QString id = 0; Fn callback; }; struct RequestChatRequest { QString requestId; Fn callback; }; class Delegate { public: [[nodiscard]] virtual Webview::ThemeParams botThemeParams() = 0; [[nodiscard]] virtual Ui::Text::MarkedContext botTextContext() = 0; [[nodiscard]] virtual auto botDownloads(bool forceCheck = false) -> const std::vector & = 0; virtual void botDownloadsAction(uint32 id, DownloadsAction type) = 0; virtual bool botHandleLocalUri(QString uri, bool keepOpen) = 0; virtual void botHandleInvoice(QString slug) = 0; virtual void botHandleMenuButton(MenuButton button) = 0; virtual bool botValidateExternalLink(QString uri) = 0; virtual void botOpenIvLink(QString uri) = 0; virtual void botSendData(QByteArray data) = 0; virtual void botSwitchInlineQuery( std::vector chatTypes, QString query) = 0; virtual void botCheckWriteAccess(Fn callback) = 0; virtual void botAllowWriteAccess(Fn callback) = 0; virtual bool botStorageWrite( QString key, std::optional value) = 0; [[nodiscard]] virtual std::optional botStorageRead( QString key) = 0; virtual void botStorageClear() = 0; virtual void botRequestEmojiStatusAccess( Fn callback) = 0; virtual void botSharePhone(Fn callback) = 0; virtual void botInvokeCustomMethod(CustomMethodRequest request) = 0; virtual void botSetEmojiStatus(SetEmojiStatusRequest request) = 0; virtual void botDownloadFile(DownloadFileRequest request) = 0; virtual void botResolveButtonEmoji(ResolveButtonEmojiRequest request) = 0; virtual void botSendPreparedMessage( SendPreparedMessageRequest request) = 0; virtual void botRequestChat(RequestChatRequest request) = 0; virtual void botVerifyAge(int age) = 0; virtual void botOpenPrivacyPolicy() = 0; virtual void botClose() = 0; }; struct Args { QString url; Webview::StorageId storageId; rpl::producer title; Ui::TitleBadgeDescriptor titleBadge; rpl::producer bottom; not_null delegate; MenuButtons menuButtons; bool fullscreen = false; bool sameOrigin = false; bool allowClipboardRead = false; rpl::producer downloadsProgress; }; class Panel final : public base::has_weak_ptr { public: explicit Panel(Args &&args); ~Panel(); void requestActivate(); void toggleProgress(bool shown); void showBox(object_ptr box); void showBox( object_ptr box, LayerOptions options, anim::type animated); void hideLayer(anim::type animated); void showToast(TextWithEntities &&text); not_null toastParent() const; void showCriticalError(const TextWithEntities &text); void showWebviewError( const QString &text, const Webview::Available &information); void updateThemeParams(const Webview::ThemeParams ¶ms); void hideForPayment(); void invoiceClosed(const QString &slug, const QString &status); [[nodiscard]] rpl::lifetime &lifetime(); private: struct ButtonArgs { bool isActive = false; bool isVisible = false; bool isProgressVisible = false; uint64 iconCustomEmojiId = 0; QString text; }; struct ExternalButtonState { ButtonArgs args; QColor color; QColor textColor; QString position; uint64 iconGeneration = 0; }; struct ExternalShellColorState { bool titleUsesTheme = true; bool bodyUsesTheme = true; bool bottomUsesTheme = true; std::optional title; std::optional body; std::optional bottom; }; struct ExternalShellAnchor { std::optional anchorGeometry; std::optional outerSize; Platform::ForeignParent transientParent; }; class Button; struct Progress; struct WebviewWithLifetime; bool showWebview(Args &&args, const Webview::ThemeParams ¶ms); void invalidateExternalShellSession(); void showExternalShellError(TextWithEntities text); bool createWebview(const Webview::ThemeParams ¶ms); void resetExternalShellIdentity(); [[nodiscard]] QWidget *webviewWindowForPopup() const; void installExternalShellDocument(); void sendExternalShellBootstrap(); void sendExternalShellMethod( const QByteArray &method, const QJsonObject &data); void sendExternalShellEvent( const QString &event, const QJsonObject &data); void sendExternalShellButton( const char *name, const QJsonObject &args); void sendExternalShellMenu(); void sendExternalShellAssets(); void handleExternalShellMenuAction(const QString &id); void requestExternalShellButtonEmoji(const QString &name); void applyExternalShellFullscreen(bool fullscreen); void sendExternalShellChrome(); void setExternalShellBlocked(bool blocked); void closeExternalShellLayer(); [[nodiscard]] ExternalShellAnchor externalShellAnchor() const; void showPopup( Webview::PopupArgs &&args, Fn done); void createWebviewBottom(); void showWebviewProgress(); void hideWebviewProgress(); void setupDownloadsProgress( not_null button, rpl::producer progress, bool fullscreen); void setTitle(rpl::producer title); void sendDataMessage(const QJsonObject &args); void switchInlineQueryMessage(const QJsonObject &args); void processSendMessageRequest(const QJsonObject &args); void processRequestChat(const QJsonObject &args); void processEmojiStatusRequest(const QJsonObject &args); void processEmojiStatusAccessRequest(); void processStorageSaveKey(const QJsonObject &args); void processStorageGetKey(const QJsonObject &args); void processStorageClear(const QJsonObject &args); void processButtonMessage( std::unique_ptr