mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Support custom attach bot icons.
This commit is contained in:
parent
426be943a2
commit
72ae2f0269
10 changed files with 297 additions and 51 deletions
|
@ -362,6 +362,7 @@ bool ResolveUsernameOrPhone(
|
||||||
.startToken = startToken,
|
.startToken = startToken,
|
||||||
.startAdminRights = adminRights,
|
.startAdminRights = adminRights,
|
||||||
.attachBotUsername = params.value(u"attach"_q),
|
.attachBotUsername = params.value(u"attach"_q),
|
||||||
|
.attachBotToggle = params.contains(u"setattach"_q),
|
||||||
.voicechatHash = (params.contains(u"livestream"_q)
|
.voicechatHash = (params.contains(u"livestream"_q)
|
||||||
? std::make_optional(params.value(u"livestream"_q))
|
? std::make_optional(params.value(u"livestream"_q))
|
||||||
: params.contains(u"videochat"_q)
|
: params.contains(u"videochat"_q)
|
||||||
|
|
|
@ -677,9 +677,14 @@ Storage::Cache::Key DocumentData::bigFileBaseCacheKey() const {
|
||||||
: Storage::Cache::Key();
|
: Storage::Cache::Key();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DocumentData::forceToCache(bool force) {
|
||||||
|
_flags |= Flag::ForceToCache;
|
||||||
|
}
|
||||||
|
|
||||||
bool DocumentData::saveToCache() const {
|
bool DocumentData::saveToCache() const {
|
||||||
return (size < Storage::kMaxFileInMemory)
|
return (size < Storage::kMaxFileInMemory)
|
||||||
&& ((type == StickerDocument)
|
&& ((type == StickerDocument)
|
||||||
|
|| (_flags & Flag::ForceToCache)
|
||||||
|| isAnimation()
|
|| isAnimation()
|
||||||
|| isVoiceMessage()
|
|| isVoiceMessage()
|
||||||
|| isWallPaper()
|
|| isWallPaper()
|
||||||
|
|
|
@ -133,6 +133,7 @@ public:
|
||||||
bool saveFromDataSilent();
|
bool saveFromDataSilent();
|
||||||
[[nodiscard]] QString filepath(bool check = false) const;
|
[[nodiscard]] QString filepath(bool check = false) const;
|
||||||
|
|
||||||
|
void forceToCache(bool force);
|
||||||
[[nodiscard]] bool saveToCache() const;
|
[[nodiscard]] bool saveToCache() const;
|
||||||
|
|
||||||
[[nodiscard]] Image *getReplyPreview(
|
[[nodiscard]] Image *getReplyPreview(
|
||||||
|
@ -268,15 +269,16 @@ public:
|
||||||
std::unique_ptr<Data::UploadState> uploadingData;
|
std::unique_ptr<Data::UploadState> uploadingData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class Flag : uchar {
|
enum class Flag : ushort {
|
||||||
StreamingMaybeYes = 0x01,
|
StreamingMaybeYes = 0x001,
|
||||||
StreamingMaybeNo = 0x02,
|
StreamingMaybeNo = 0x002,
|
||||||
StreamingPlaybackFailed = 0x04,
|
StreamingPlaybackFailed = 0x004,
|
||||||
ImageType = 0x08,
|
ImageType = 0x008,
|
||||||
DownloadCancelled = 0x10,
|
DownloadCancelled = 0x010,
|
||||||
LoadedInMediaCache = 0x20,
|
LoadedInMediaCache = 0x020,
|
||||||
HasAttachedStickers = 0x40,
|
HasAttachedStickers = 0x040,
|
||||||
InlineThumbnailIsPath = 0x80,
|
InlineThumbnailIsPath = 0x080,
|
||||||
|
ForceToCache = 0x100,
|
||||||
};
|
};
|
||||||
using Flags = base::flags<Flag>;
|
using Flags = base::flags<Flag>;
|
||||||
friend constexpr bool is_flag_type(Flag) { return true; };
|
friend constexpr bool is_flag_type(Flag) { return true; };
|
||||||
|
|
|
@ -497,6 +497,10 @@ HistoryWidget::HistoryWidget(
|
||||||
if (_history && _history->peer->isUser()) {
|
if (_history && _history->peer->isUser()) {
|
||||||
_attachToggle->installEventFilter(_attachBotsMenu.get());
|
_attachToggle->installEventFilter(_attachBotsMenu.get());
|
||||||
}
|
}
|
||||||
|
_attachBotsMenu->heightValue(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
moveFieldControls();
|
||||||
|
}, _attachBotsMenu->lifetime());
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "inline_bots/bot_attach_web_view.h"
|
#include "inline_bots/bot_attach_web_view.h"
|
||||||
|
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
|
#include "data/data_document.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "main/main_domain.h"
|
#include "main/main_domain.h"
|
||||||
#include "storage/storage_domain.h"
|
#include "storage/storage_domain.h"
|
||||||
#include "info/profile/info_profile_values.h"
|
#include "info/profile/info_profile_values.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "ui/widgets/dropdown_menu.h"
|
|
||||||
#include "ui/toasts/common_toasts.h"
|
#include "ui/toasts/common_toasts.h"
|
||||||
#include "ui/chat/attach/attach_bot_webview.h"
|
#include "ui/chat/attach/attach_bot_webview.h"
|
||||||
|
#include "ui/widgets/dropdown_menu.h"
|
||||||
|
#include "ui/widgets/menu/menu_item_base.h"
|
||||||
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
@ -33,15 +37,32 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kProlongTimeout = 60 * crl::time(1000);
|
constexpr auto kProlongTimeout = 60 * crl::time(1000);
|
||||||
|
|
||||||
[[nodiscard]] UserData *ParseAttachBot(
|
struct ParsedBot {
|
||||||
|
UserData *bot = nullptr;
|
||||||
|
bool inactive = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] std::optional<AttachWebViewBot> ParseAttachBot(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
const MTPAttachMenuBot &bot) {
|
const MTPAttachMenuBot &bot) {
|
||||||
return bot.match([&](const MTPDattachMenuBot &data) {
|
auto result = bot.match([&](const MTPDattachMenuBot &data) {
|
||||||
const auto user = session->data().userLoaded(UserId(data.vbot_id()));
|
const auto user = session->data().userLoaded(UserId(data.vbot_id()));
|
||||||
return (user && user->isBot() && user->botInfo->supportsAttachMenu)
|
const auto good = user
|
||||||
? user
|
&& user->isBot()
|
||||||
: nullptr;
|
&& user->botInfo->supportsAttachMenu;
|
||||||
|
return good
|
||||||
|
? AttachWebViewBot{
|
||||||
|
.user = user,
|
||||||
|
.icon = session->data().processDocument(
|
||||||
|
data.vattach_menu_icon()),
|
||||||
|
.name = qs(data.vattach_menu_name()),
|
||||||
|
.inactive = data.is_inactive(),
|
||||||
|
} : std::optional<AttachWebViewBot>();
|
||||||
});
|
});
|
||||||
|
if (result) {
|
||||||
|
result->icon->forceToCache(true);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] base::flat_set<not_null<AttachWebView*>> &ActiveWebViews() {
|
[[nodiscard]] base::flat_set<not_null<AttachWebView*>> &ActiveWebViews() {
|
||||||
|
@ -49,6 +70,138 @@ constexpr auto kProlongTimeout = 60 * crl::time(1000);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BotAction final : public Ui::Menu::ItemBase {
|
||||||
|
public:
|
||||||
|
BotAction(
|
||||||
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
const style::Menu &st,
|
||||||
|
const AttachWebViewBot &bot,
|
||||||
|
Fn<void()> callback);
|
||||||
|
|
||||||
|
bool isEnabled() const override;
|
||||||
|
not_null<QAction*> action() const override;
|
||||||
|
|
||||||
|
void handleKeyPress(not_null<QKeyEvent*> e) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QPoint prepareRippleStartPosition() const override;
|
||||||
|
QImage prepareRippleMask() const override;
|
||||||
|
|
||||||
|
int contentHeight() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void prepare();
|
||||||
|
void paint(Painter &p);
|
||||||
|
|
||||||
|
const not_null<QAction*> _dummyAction;
|
||||||
|
const style::Menu &_st;
|
||||||
|
const AttachWebViewBot _bot;
|
||||||
|
|
||||||
|
Ui::Text::String _text;
|
||||||
|
int _textWidth = 0;
|
||||||
|
const int _height;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
BotAction::BotAction(
|
||||||
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
const style::Menu &st,
|
||||||
|
const AttachWebViewBot &bot,
|
||||||
|
Fn<void()> callback)
|
||||||
|
: ItemBase(parent, st)
|
||||||
|
, _dummyAction(new QAction(parent))
|
||||||
|
, _st(st)
|
||||||
|
, _bot(bot)
|
||||||
|
, _height(_st.itemPadding.top()
|
||||||
|
+ _st.itemStyle.font->height
|
||||||
|
+ _st.itemPadding.bottom()) {
|
||||||
|
setAcceptBoth(true);
|
||||||
|
initResizeHook(parent->sizeValue());
|
||||||
|
setClickedCallback(std::move(callback));
|
||||||
|
|
||||||
|
paintRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
Painter p(this);
|
||||||
|
paint(p);
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
|
enableMouseSelecting();
|
||||||
|
prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BotAction::paint(Painter &p) {
|
||||||
|
const auto selected = isSelected();
|
||||||
|
if (selected && _st.itemBgOver->c.alpha() < 255) {
|
||||||
|
p.fillRect(0, 0, width(), _height, _st.itemBg);
|
||||||
|
}
|
||||||
|
p.fillRect(0, 0, width(), _height, selected ? _st.itemBgOver : _st.itemBg);
|
||||||
|
if (isEnabled()) {
|
||||||
|
paintRipple(p, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto normalHeight = _st.itemPadding.top()
|
||||||
|
+ _st.itemStyle.font->height
|
||||||
|
+ _st.itemPadding.bottom();
|
||||||
|
const auto deltaHeight = _height - normalHeight;
|
||||||
|
st::menuIconDelete.paint(
|
||||||
|
p,
|
||||||
|
_st.itemIconPosition + QPoint(0, deltaHeight / 2),
|
||||||
|
width());
|
||||||
|
|
||||||
|
p.setPen(selected ? _st.itemFgOver : _st.itemFg);
|
||||||
|
_text.drawLeftElided(
|
||||||
|
p,
|
||||||
|
_st.itemPadding.left(),
|
||||||
|
_st.itemPadding.top(),
|
||||||
|
_textWidth,
|
||||||
|
width());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BotAction::prepare() {
|
||||||
|
_text.setMarkedText(_st.itemStyle, { _bot.name });
|
||||||
|
const auto textWidth = _text.maxWidth();
|
||||||
|
const auto &padding = _st.itemPadding;
|
||||||
|
|
||||||
|
const auto goodWidth = padding.left()
|
||||||
|
+ textWidth
|
||||||
|
+ padding.right();
|
||||||
|
|
||||||
|
const auto w = std::clamp(goodWidth, _st.widthMin, _st.widthMax);
|
||||||
|
_textWidth = w - (goodWidth - textWidth);
|
||||||
|
setMinWidth(w);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BotAction::isEnabled() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
not_null<QAction*> BotAction::action() const {
|
||||||
|
return _dummyAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint BotAction::prepareRippleStartPosition() const {
|
||||||
|
return mapFromGlobal(QCursor::pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage BotAction::prepareRippleMask() const {
|
||||||
|
return Ui::RippleAnimation::rectMask(size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int BotAction::contentHeight() const {
|
||||||
|
return _height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BotAction::handleKeyPress(not_null<QKeyEvent*> e) {
|
||||||
|
if (!isSelected()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto key = e->key();
|
||||||
|
if (key == Qt::Key_Enter || key == Qt::Key_Return) {
|
||||||
|
setClicked(Ui::Menu::TriggeredSource::Keyboard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
AttachWebView::AttachWebView(not_null<Main::Session*> session)
|
AttachWebView::AttachWebView(not_null<Main::Session*> session)
|
||||||
|
@ -115,11 +268,11 @@ void AttachWebView::request(const WebViewButton &button) {
|
||||||
_session->data().processUsers(data.vusers());
|
_session->data().processUsers(data.vusers());
|
||||||
const auto &received = data.vbot();
|
const auto &received = data.vbot();
|
||||||
if (const auto bot = ParseAttachBot(_session, received)) {
|
if (const auto bot = ParseAttachBot(_session, received)) {
|
||||||
if (_bot != bot) {
|
if (_bot != bot->user) {
|
||||||
cancel();
|
cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
requestAddToMenu([=] {
|
confirmAddToMenu(*bot, [=] {
|
||||||
request(button);
|
request(button);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -156,15 +309,13 @@ void AttachWebView::requestBots() {
|
||||||
_attachBots.clear();
|
_attachBots.clear();
|
||||||
_attachBots.reserve(data.vbots().v.size());
|
_attachBots.reserve(data.vbots().v.size());
|
||||||
for (const auto &bot : data.vbots().v) {
|
for (const auto &bot : data.vbots().v) {
|
||||||
bot.match([&](const MTPDattachMenuBot &data) {
|
if (auto parsed = ParseAttachBot(_session, bot)) {
|
||||||
if (data.is_inactive()) {
|
if (!parsed->inactive) {
|
||||||
return;
|
parsed->media = parsed->icon->createMediaView();
|
||||||
|
parsed->icon->save(Data::FileOrigin(), {});
|
||||||
|
_attachBots.push_back(std::move(*parsed));
|
||||||
}
|
}
|
||||||
_attachBots.push_back({
|
}
|
||||||
.user = _session->data().user(data.vbot_id()),
|
|
||||||
.name = qs(data.vattach_menu_name()),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
_attachBotsUpdates.fire({});
|
_attachBotsUpdates.fire({});
|
||||||
});
|
});
|
||||||
|
@ -173,6 +324,49 @@ void AttachWebView::requestBots() {
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AttachWebView::requestAddToMenu(not_null<UserData*> bot) {
|
||||||
|
if (!bot->isBot() || !bot->botInfo->supportsAttachMenu) {
|
||||||
|
return;
|
||||||
|
} else if (_addToMenuId) {
|
||||||
|
if (_addToMenuBot == bot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_session->api().request(base::take(_addToMenuId)).cancel();
|
||||||
|
}
|
||||||
|
_addToMenuBot = bot;
|
||||||
|
_addToMenuId = _session->api().request(MTPmessages_GetAttachMenuBot(
|
||||||
|
bot->inputUser
|
||||||
|
)).done([=](const MTPAttachMenuBotsBot &result) {
|
||||||
|
_addToMenuId = 0;
|
||||||
|
const auto requested = base::take(_addToMenuBot);
|
||||||
|
result.match([&](const MTPDattachMenuBotsBot &data) {
|
||||||
|
_session->data().processUsers(data.vusers());
|
||||||
|
if (const auto bot = ParseAttachBot(_session, data.vbot())) {
|
||||||
|
if (requested == bot->user) {
|
||||||
|
if (bot->inactive) {
|
||||||
|
confirmAddToMenu(*bot);
|
||||||
|
} else {
|
||||||
|
requestBots();
|
||||||
|
Ui::ShowMultilineToast({
|
||||||
|
.text = { u"Bot is already added."_q },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).fail([=] {
|
||||||
|
_addToMenuId = 0;
|
||||||
|
_addToMenuBot = nullptr;
|
||||||
|
Ui::ShowMultilineToast({
|
||||||
|
.text = { u"Bot cannot be added to the menu."_q },
|
||||||
|
});
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachWebView::removeFromMenu(not_null<UserData*> bot) {
|
||||||
|
toggleInMenu(bot, false, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void AttachWebView::resolve() {
|
void AttachWebView::resolve() {
|
||||||
if (!_bot) {
|
if (!_bot) {
|
||||||
requestByUsername();
|
requestByUsername();
|
||||||
|
@ -327,12 +521,14 @@ void AttachWebView::started(uint64 queryId) {
|
||||||
}, _panel->lifetime());
|
}, _panel->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachWebView::requestAddToMenu(Fn<void()> callback) {
|
void AttachWebView::confirmAddToMenu(
|
||||||
Expects(_bot != nullptr);
|
AttachWebViewBot bot,
|
||||||
|
Fn<void()> callback) {
|
||||||
const auto done = [=](Fn<void()> close) {
|
const auto done = [=](Fn<void()> close) {
|
||||||
toggleInMenu( true, [=] {
|
toggleInMenu(bot.user, true, [=] {
|
||||||
callback();
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
close();
|
close();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -341,21 +537,24 @@ void AttachWebView::requestAddToMenu(Fn<void()> callback) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_confirmAddBox = active->show(Ui::MakeConfirmBox({
|
_confirmAddBox = active->show(Ui::MakeConfirmBox({
|
||||||
u"Do you want to? "_q + _bot->name,
|
u"Do you want to? "_q + bot.name,
|
||||||
done,
|
done,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachWebView::toggleInMenu(bool enabled, Fn<void()> callback) {
|
void AttachWebView::toggleInMenu(
|
||||||
Expects(_bot != nullptr);
|
not_null<UserData*> bot,
|
||||||
|
bool enabled,
|
||||||
_requestId = _session->api().request(MTPmessages_ToggleBotInAttachMenu(
|
Fn<void()> callback) {
|
||||||
_bot->inputUser,
|
_session->api().request(MTPmessages_ToggleBotInAttachMenu(
|
||||||
|
bot->inputUser,
|
||||||
MTP_bool(enabled)
|
MTP_bool(enabled)
|
||||||
)).done([=] {
|
)).done([=] {
|
||||||
_requestId = 0;
|
_requestId = 0;
|
||||||
requestBots();
|
requestBots();
|
||||||
callback();
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
}).fail([=] {
|
}).fail([=] {
|
||||||
cancel();
|
cancel();
|
||||||
}).send();
|
}).send();
|
||||||
|
@ -372,12 +571,12 @@ std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
|
||||||
const auto refresh = [=] {
|
const auto refresh = [=] {
|
||||||
raw->clearActions();
|
raw->clearActions();
|
||||||
for (const auto &bot : bots->attachBots()) {
|
for (const auto &bot : bots->attachBots()) {
|
||||||
raw->addAction(bot.name, [=, bot = bot.user]{
|
raw->addAction(base::make_unique_q<BotAction>(raw, bot, raw->menu()->st(), [=] {
|
||||||
const auto active = controller->activeChatCurrent();
|
const auto active = controller->activeChatCurrent();
|
||||||
if (const auto history = active.history()) {
|
if (const auto history = active.history()) {
|
||||||
bots->request(history->peer, bot);
|
bots->request(history->peer, bot.user);
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
refresh();
|
refresh();
|
||||||
|
|
|
@ -27,11 +27,18 @@ namespace Window {
|
||||||
class SessionController;
|
class SessionController;
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
class DocumentMedia;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
namespace InlineBots {
|
namespace InlineBots {
|
||||||
|
|
||||||
struct AttachWebViewBot {
|
struct AttachWebViewBot {
|
||||||
not_null<UserData*> user;
|
not_null<UserData*> user;
|
||||||
|
not_null<DocumentData*> icon;
|
||||||
|
std::shared_ptr<Data::DocumentMedia> media;
|
||||||
QString name;
|
QString name;
|
||||||
|
bool inactive = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AttachWebView final : public base::has_weak_ptr {
|
class AttachWebView final : public base::has_weak_ptr {
|
||||||
|
@ -62,6 +69,9 @@ public:
|
||||||
return _attachBotsUpdates.events();
|
return _attachBotsUpdates.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void requestAddToMenu(not_null<UserData*> bot);
|
||||||
|
void removeFromMenu(not_null<UserData*> bot);
|
||||||
|
|
||||||
static void ClearAll();
|
static void ClearAll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -72,13 +82,18 @@ private:
|
||||||
const QString &username,
|
const QString &username,
|
||||||
Fn<void(not_null<PeerData*>)> done);
|
Fn<void(not_null<PeerData*>)> done);
|
||||||
|
|
||||||
void toggleInMenu(bool enabled, Fn<void()> callback);
|
void toggleInMenu(
|
||||||
|
not_null<UserData*> bot,
|
||||||
|
bool enabled,
|
||||||
|
Fn<void()> callback);
|
||||||
|
|
||||||
void show(
|
void show(
|
||||||
uint64 queryId,
|
uint64 queryId,
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &buttonText = QString());
|
const QString &buttonText = QString());
|
||||||
void requestAddToMenu(Fn<void()> callback);
|
void confirmAddToMenu(
|
||||||
|
AttachWebViewBot bot,
|
||||||
|
Fn<void()> callback = nullptr);
|
||||||
void started(uint64 queryId);
|
void started(uint64 queryId);
|
||||||
|
|
||||||
const not_null<Main::Session*> _session;
|
const not_null<Main::Session*> _session;
|
||||||
|
@ -95,6 +110,9 @@ private:
|
||||||
uint64 _botsHash = 0;
|
uint64 _botsHash = 0;
|
||||||
mtpRequestId _botsRequestId = 0;
|
mtpRequestId _botsRequestId = 0;
|
||||||
|
|
||||||
|
UserData *_addToMenuBot = nullptr;
|
||||||
|
mtpRequestId _addToMenuId = 0;
|
||||||
|
|
||||||
std::vector<AttachWebViewBot> _attachBots;
|
std::vector<AttachWebViewBot> _attachBots;
|
||||||
rpl::event_stream<> _attachBotsUpdates;
|
rpl::event_stream<> _attachBotsUpdates;
|
||||||
|
|
||||||
|
|
|
@ -478,7 +478,17 @@ std::unique_ptr<Panel> Show(Args &&args) {
|
||||||
std::move(args.sendData),
|
std::move(args.sendData),
|
||||||
std::move(args.close),
|
std::move(args.close),
|
||||||
std::move(args.themeParams));
|
std::move(args.themeParams));
|
||||||
result->showWebview(args.url, std::move(args.bottom));
|
if (!result->showWebview(args.url, std::move(args.bottom))) {
|
||||||
|
const auto available = Webview::Availability();
|
||||||
|
if (available.error != Webview::Available::Error::None) {
|
||||||
|
result->showWebviewError(
|
||||||
|
tr::lng_payments_webview_no_card(tr::now),
|
||||||
|
available);
|
||||||
|
} else {
|
||||||
|
result->showCriticalError({
|
||||||
|
"Error: Could not initialize WebView." });
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,9 @@ public:
|
||||||
void showBox(object_ptr<BoxContent> box);
|
void showBox(object_ptr<BoxContent> box);
|
||||||
void showToast(const TextWithEntities &text);
|
void showToast(const TextWithEntities &text);
|
||||||
void showCriticalError(const TextWithEntities &text);
|
void showCriticalError(const TextWithEntities &text);
|
||||||
|
void showWebviewError(
|
||||||
|
const QString &text,
|
||||||
|
const Webview::Available &information);
|
||||||
|
|
||||||
void updateThemeParams(const QByteArray &json);
|
void updateThemeParams(const QByteArray &json);
|
||||||
|
|
||||||
|
@ -53,9 +56,6 @@ private:
|
||||||
bool createWebview();
|
bool createWebview();
|
||||||
void showWebviewProgress();
|
void showWebviewProgress();
|
||||||
void hideWebviewProgress();
|
void hideWebviewProgress();
|
||||||
void showWebviewError(
|
|
||||||
const QString &text,
|
|
||||||
const Webview::Available &information);
|
|
||||||
void setTitle(rpl::producer<QString> title);
|
void setTitle(rpl::producer<QString> title);
|
||||||
|
|
||||||
[[nodiscard]] bool progressWithBackground() const;
|
[[nodiscard]] bool progressWithBackground() const;
|
||||||
|
|
|
@ -383,16 +383,22 @@ void SessionNavigation::showPeerByLinkResolved(
|
||||||
msgId = ShowAtUnreadMsgId;
|
msgId = ShowAtUnreadMsgId;
|
||||||
}
|
}
|
||||||
const auto attachBotUsername = info.attachBotUsername;
|
const auto attachBotUsername = info.attachBotUsername;
|
||||||
if (user && user->isBot()) {
|
if (user
|
||||||
|
&& user->isBot()
|
||||||
|
&& user->botInfo->startToken != info.startToken) {
|
||||||
user->botInfo->startToken = info.startToken;
|
user->botInfo->startToken = info.startToken;
|
||||||
user->session().changes().peerUpdated(
|
user->session().changes().peerUpdated(
|
||||||
user,
|
user,
|
||||||
Data::PeerUpdate::Flag::BotStartToken);
|
Data::PeerUpdate::Flag::BotStartToken);
|
||||||
}
|
}
|
||||||
crl::on_main(this, [=] {
|
if (user && info.attachBotToggle) {
|
||||||
showPeerHistory(peer->id, params, msgId);
|
user->session().attachWebView().requestAddToMenu(user);
|
||||||
peer->session().attachWebView().request(peer, attachBotUsername);
|
} else {
|
||||||
});
|
crl::on_main(this, [=] {
|
||||||
|
showPeerHistory(peer->id, params, msgId);
|
||||||
|
peer->session().attachWebView().request(peer, attachBotUsername);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,6 +196,7 @@ public:
|
||||||
QString startToken;
|
QString startToken;
|
||||||
ChatAdminRights startAdminRights;
|
ChatAdminRights startAdminRights;
|
||||||
QString attachBotUsername;
|
QString attachBotUsername;
|
||||||
|
bool attachBotToggle = false;
|
||||||
std::optional<QString> voicechatHash;
|
std::optional<QString> voicechatHash;
|
||||||
FullMsgId clickFromMessageId;
|
FullMsgId clickFromMessageId;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue