mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-06 23:24:01 +02:00
Implement emoji status set from miniapps.
This commit is contained in:
parent
21487641c1
commit
4198203a7f
15 changed files with 281 additions and 11 deletions
|
@ -3418,6 +3418,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_bot_add_to_side_menu_done" = "Bot added to the main menu.";
|
"lng_bot_add_to_side_menu_done" = "Bot added to the main menu.";
|
||||||
"lng_bot_no_scan_qr" = "QR Codes for bots are not supported on Desktop. Please use one of Telegram's mobile apps.";
|
"lng_bot_no_scan_qr" = "QR Codes for bots are not supported on Desktop. Please use one of Telegram's mobile apps.";
|
||||||
"lng_bot_no_share_story" = "Sharing to Stories is not supported on Desktop. Please use one of Telegram's mobile apps.";
|
"lng_bot_no_share_story" = "Sharing to Stories is not supported on Desktop. Please use one of Telegram's mobile apps.";
|
||||||
|
"lng_bot_emoji_status_confirm" = "Confirm";
|
||||||
|
"lng_bot_emoji_status_title" = "Set Emoji Status";
|
||||||
|
"lng_bot_emoji_status_text" = "Do you want to set this emoji status suggested by {bot}?";
|
||||||
|
|
||||||
"lng_bot_status_users#one" = "{count} monthly user";
|
"lng_bot_status_users#one" = "{count} monthly user";
|
||||||
"lng_bot_status_users#other" = "{count} monthly users";
|
"lng_bot_status_users#other" = "{count} monthly users";
|
||||||
|
|
|
@ -1225,6 +1225,9 @@ not_null<CustomEmojiManager::Listener*> Reactions::resolveListener() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reactions::customEmojiResolveDone(not_null<DocumentData*> document) {
|
void Reactions::customEmojiResolveDone(not_null<DocumentData*> document) {
|
||||||
|
if (!document->sticker()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto id = ReactionId{ { document->id } };
|
const auto id = ReactionId{ { document->id } };
|
||||||
const auto favorite = (_unresolvedFavoriteId == id);
|
const auto favorite = (_unresolvedFavoriteId == id);
|
||||||
const auto i = _unresolvedTop.find(id);
|
const auto i = _unresolvedTop.find(id);
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct BotInfo {
|
||||||
bool cantJoinGroups : 1 = false;
|
bool cantJoinGroups : 1 = false;
|
||||||
bool supportsAttachMenu : 1 = false;
|
bool supportsAttachMenu : 1 = false;
|
||||||
bool canEditInformation : 1 = false;
|
bool canEditInformation : 1 = false;
|
||||||
|
bool canManageEmojiStatus : 1 = false;
|
||||||
bool supportsBusiness : 1 = false;
|
bool supportsBusiness : 1 = false;
|
||||||
bool hasMainApp : 1 = false;
|
bool hasMainApp : 1 = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -652,22 +652,27 @@ void CustomEmojiManager::unregisterListener(not_null<Listener*> listener) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<not_null<DocumentData*>> CustomEmojiManager::resolve(
|
auto CustomEmojiManager::resolve(DocumentId documentId)
|
||||||
DocumentId documentId) {
|
-> rpl::producer<not_null<DocumentData*>, rpl::empty_error> {
|
||||||
return [=](auto consumer) {
|
return [=](auto consumer) {
|
||||||
auto result = rpl::lifetime();
|
auto result = rpl::lifetime();
|
||||||
const auto put = [=](not_null<DocumentData*> document) {
|
const auto put = [=](
|
||||||
|
not_null<DocumentData*> document,
|
||||||
|
bool resolved = true) {
|
||||||
if (!document->sticker()) {
|
if (!document->sticker()) {
|
||||||
|
if (resolved) {
|
||||||
|
consumer.put_error({});
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
consumer.put_next_copy(document);
|
consumer.put_next_copy(document);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
if (!put(owner().document(documentId))) {
|
if (!put(owner().document(documentId), false)) {
|
||||||
const auto listener = new CallbackListener(put);
|
const auto listener = result.make_state<CallbackListener>(put);
|
||||||
|
resolve(documentId, listener);
|
||||||
result.add([=] {
|
result.add([=] {
|
||||||
unregisterListener(listener);
|
unregisterListener(listener);
|
||||||
delete listener;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -763,6 +768,9 @@ void CustomEmojiManager::request() {
|
||||||
requestFinished();
|
requestFinished();
|
||||||
}).fail([=] {
|
}).fail([=] {
|
||||||
LOG(("API Error: Failed to get documents for emoji."));
|
LOG(("API Error: Failed to get documents for emoji."));
|
||||||
|
for (const auto &id : ids) {
|
||||||
|
processListeners(_owner->document(id.v));
|
||||||
|
}
|
||||||
requestFinished();
|
requestFinished();
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
@ -792,7 +800,8 @@ void CustomEmojiManager::processLoaders(not_null<DocumentData*> document) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomEmojiManager::processListeners(not_null<DocumentData*> document) {
|
void CustomEmojiManager::processListeners(
|
||||||
|
not_null<DocumentData*> document) {
|
||||||
const auto id = document->id;
|
const auto id = document->id;
|
||||||
if (const auto listeners = _resolvers.take(id)) {
|
if (const auto listeners = _resolvers.take(id)) {
|
||||||
for (const auto &listener : *listeners) {
|
for (const auto &listener : *listeners) {
|
||||||
|
|
|
@ -66,8 +66,8 @@ public:
|
||||||
void resolve(DocumentId documentId, not_null<Listener*> listener);
|
void resolve(DocumentId documentId, not_null<Listener*> listener);
|
||||||
void unregisterListener(not_null<Listener*> listener);
|
void unregisterListener(not_null<Listener*> listener);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<not_null<DocumentData*>> resolve(
|
[[nodiscard]] auto resolve(DocumentId documentId)
|
||||||
DocumentId documentId);
|
-> rpl::producer<not_null<DocumentData*>, rpl::empty_error>;
|
||||||
|
|
||||||
[[nodiscard]] std::unique_ptr<Ui::CustomEmoji::Loader> createLoader(
|
[[nodiscard]] std::unique_ptr<Ui::CustomEmoji::Loader> createLoader(
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace {
|
||||||
text.size(),
|
text.size(),
|
||||||
Data::SerializeCustomEmojiId(document)) },
|
Data::SerializeCustomEmojiId(document)) },
|
||||||
};
|
};
|
||||||
});
|
}) | rpl::map_error_to_done();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<TextWithEntities> PeerCustomStatus(
|
[[nodiscard]] rpl::producer<TextWithEntities> PeerCustomStatus(
|
||||||
|
|
|
@ -108,6 +108,9 @@ CustomEmoji::CustomEmoji(
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomEmoji::customEmojiResolveDone(not_null<DocumentData*> document) {
|
void CustomEmoji::customEmojiResolveDone(not_null<DocumentData*> document) {
|
||||||
|
if (!document->sticker()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_resolving = false;
|
_resolving = false;
|
||||||
const auto id = document->id;
|
const auto id = document->id;
|
||||||
for (auto &line : _lines) {
|
for (auto &line : _lines) {
|
||||||
|
|
|
@ -162,7 +162,7 @@ void TopicIconView::setupPlayer(not_null<Data::ForumTopic*> topic) {
|
||||||
id
|
id
|
||||||
) | rpl::map([=](not_null<DocumentData*> document) {
|
) | rpl::map([=](not_null<DocumentData*> document) {
|
||||||
return document.get();
|
return document.get();
|
||||||
});
|
}) | rpl::map_error_to_done();
|
||||||
}) | rpl::flatten_latest(
|
}) | rpl::flatten_latest(
|
||||||
) | rpl::map([=](DocumentData *document)
|
) | rpl::map([=](DocumentData *document)
|
||||||
-> rpl::producer<std::shared_ptr<StickerPlayer>> {
|
-> rpl::producer<std::shared_ptr<StickerPlayer>> {
|
||||||
|
|
|
@ -26,12 +26,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_document_media.h"
|
#include "data/data_document_media.h"
|
||||||
|
#include "data/data_emoji_statuses.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
#include "data/data_peer_bot_command.h"
|
#include "data/data_peer_bot_command.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_web_page.h"
|
#include "data/data_web_page.h"
|
||||||
#include "data/stickers/data_custom_emoji.h"
|
#include "data/stickers/data_custom_emoji.h"
|
||||||
|
#include "data/stickers/data_stickers.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "info/profile/info_profile_values.h"
|
#include "info/profile/info_profile_values.h"
|
||||||
|
@ -43,6 +45,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "payments/payments_checkout_process.h"
|
#include "payments/payments_checkout_process.h"
|
||||||
#include "payments/payments_non_panel_process.h"
|
#include "payments/payments_non_panel_process.h"
|
||||||
|
#include "settings/settings_premium.h"
|
||||||
#include "storage/storage_account.h"
|
#include "storage/storage_account.h"
|
||||||
#include "storage/storage_domain.h"
|
#include "storage/storage_domain.h"
|
||||||
#include "ui/basic_click_handlers.h"
|
#include "ui/basic_click_handlers.h"
|
||||||
|
@ -428,6 +431,124 @@ void FillBotUsepic(
|
||||||
Ui::IconWithTitle(box->verticalLayout(), userpic, title, aboutLabel);
|
Ui::IconWithTitle(box->verticalLayout(), userpic, title, aboutLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Ui::RpWidget> MakeEmojiSetStatusPreview(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
not_null<DocumentData*> document) {
|
||||||
|
auto result = std::make_unique<Ui::RpWidget>(parent);
|
||||||
|
|
||||||
|
const auto size = st::chatGiveawayPeerSize;
|
||||||
|
const auto padding = st::chatGiveawayPeerPadding;
|
||||||
|
|
||||||
|
const auto raw = result.get();
|
||||||
|
|
||||||
|
const auto width = raw->lifetime().make_state<int>();
|
||||||
|
const auto name = raw->lifetime().make_state<Ui::FlatLabel>(
|
||||||
|
raw,
|
||||||
|
rpl::single(peer->name()),
|
||||||
|
st::botEmojiStatusName);
|
||||||
|
auto emojiText = TextWithEntities();
|
||||||
|
const auto emoji = raw->lifetime().make_state<Ui::FlatLabel>(
|
||||||
|
raw,
|
||||||
|
rpl::single(emojiText),
|
||||||
|
st::botEmojiStatusName);
|
||||||
|
const auto userpic = raw->lifetime().make_state<Ui::UserpicButton>(
|
||||||
|
raw,
|
||||||
|
peer,
|
||||||
|
st::botEmojiStatusUserpic);
|
||||||
|
|
||||||
|
raw->resize(size, size);
|
||||||
|
raw->sizeValue() | rpl::start_with_next([=](QSize outer) {
|
||||||
|
const auto full = outer.width();
|
||||||
|
const auto decorations = size
|
||||||
|
+ padding.left()
|
||||||
|
+ padding.right()
|
||||||
|
+ emoji->width()
|
||||||
|
+ st::normalFont->spacew;
|
||||||
|
const auto inner = full - decorations;
|
||||||
|
const auto use = std::min(inner, name->textMaxWidth());
|
||||||
|
*width = use + decorations;
|
||||||
|
const auto left = (full - *width) / 2;
|
||||||
|
if (inner > 0) {
|
||||||
|
userpic->moveToLeft(left, 0, outer.width());
|
||||||
|
emoji->moveToLeft(
|
||||||
|
left + *width - padding.right() - emoji->width(),
|
||||||
|
padding.top(),
|
||||||
|
outer.width());
|
||||||
|
name->resizeToWidth(use);
|
||||||
|
name->moveToLeft(
|
||||||
|
left + size + padding.left(),
|
||||||
|
padding.top(),
|
||||||
|
outer.width());
|
||||||
|
}
|
||||||
|
}, raw->lifetime());
|
||||||
|
raw->paintRequest() | rpl::start_with_next([=] {
|
||||||
|
auto p = QPainter(raw);
|
||||||
|
const auto left = (raw->width() - *width) / 2;
|
||||||
|
const auto skip = size / 2;
|
||||||
|
p.setClipRect(left + skip, 0, *width - skip, size);
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(st::windowBgOver);
|
||||||
|
p.drawRoundedRect(left, 0, *width, size, skip, skip);
|
||||||
|
}, raw->lifetime());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfirmEmojiStatusBox(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
not_null<UserData*> bot,
|
||||||
|
not_null<DocumentData*> document,
|
||||||
|
TimeId until,
|
||||||
|
Fn<void(bool)> done) {
|
||||||
|
box->setNoContentMargin(true);
|
||||||
|
|
||||||
|
auto owned = Settings::MakeEmojiStatusPreview(box, document);
|
||||||
|
const auto preview = box->addRow(
|
||||||
|
object_ptr<Ui::RpWidget>::fromRaw(owned.release()));
|
||||||
|
preview->resize(preview->width(), st::botEmojiStatusPreviewHeight);
|
||||||
|
|
||||||
|
const auto set = box->lifetime().make_state<bool>();
|
||||||
|
|
||||||
|
box->addRow(object_ptr<Ui::FlatLabel>(
|
||||||
|
box,
|
||||||
|
tr::lng_bot_emoji_status_title(),
|
||||||
|
st::botEmojiStatusTitle));
|
||||||
|
AddSkip(box->verticalLayout());
|
||||||
|
|
||||||
|
box->addRow(object_ptr<Ui::FlatLabel>(
|
||||||
|
box,
|
||||||
|
tr::lng_bot_emoji_status_text(
|
||||||
|
lt_bot,
|
||||||
|
rpl::single(Ui::Text::Bold(bot->name())),
|
||||||
|
Ui::Text::RichLangValue),
|
||||||
|
st::botEmojiStatusText));
|
||||||
|
|
||||||
|
AddSkip(box->verticalLayout());
|
||||||
|
|
||||||
|
auto ownedSet = MakeEmojiSetStatusPreview(
|
||||||
|
box,
|
||||||
|
document->session().user(),
|
||||||
|
document);
|
||||||
|
box->addRow(
|
||||||
|
object_ptr<Ui::RpWidget>::fromRaw(ownedSet.release()));
|
||||||
|
|
||||||
|
box->addButton(tr::lng_bot_emoji_status_confirm(), [=] {
|
||||||
|
document->owner().emojiStatuses().set(document->id, until);
|
||||||
|
*set = true;
|
||||||
|
box->closeBox();
|
||||||
|
done(true);
|
||||||
|
});
|
||||||
|
box->addButton(tr::lng_cancel(), [=] {
|
||||||
|
const auto was = *set;
|
||||||
|
box->closeBox();
|
||||||
|
if (!was) {
|
||||||
|
done(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
class BotAction final : public Ui::Menu::ItemBase {
|
class BotAction final : public Ui::Menu::ItemBase {
|
||||||
public:
|
public:
|
||||||
BotAction(
|
BotAction(
|
||||||
|
@ -1514,6 +1635,32 @@ void WebViewInstance::botInvokeCustomMethod(
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebViewInstance::botSetEmojiStatus(
|
||||||
|
Ui::BotWebView::SetEmojiStatusRequest request) {
|
||||||
|
const auto bot = _bot;
|
||||||
|
const auto panel = _panel.get();
|
||||||
|
const auto callback = request.callback;
|
||||||
|
const auto until = request.expirationDate;
|
||||||
|
if (!panel) {
|
||||||
|
callback(u"UNKNOWN_ERROR"_q);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_session->data().customEmojiManager().resolve(
|
||||||
|
request.customEmojiId
|
||||||
|
) | rpl::start_with_next_error([=](not_null<DocumentData*> document) {
|
||||||
|
const auto sticker = document->sticker();
|
||||||
|
if (!sticker || sticker->setType != Data::StickersType::Emoji) {
|
||||||
|
callback(u"SUGGESTED_EMOJI_INVALID"_q);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto done = [=](bool success) {
|
||||||
|
callback(success ? QString() : u"USER_DECLINED"_q);
|
||||||
|
};
|
||||||
|
panel->showBox(
|
||||||
|
Box(ConfirmEmojiStatusBox, bot, document, until, done));
|
||||||
|
}, [=] { callback(u"SUGGESTED_EMOJI_INVALID"_q); }, panel->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
void WebViewInstance::botOpenPrivacyPolicy() {
|
void WebViewInstance::botOpenPrivacyPolicy() {
|
||||||
const auto bot = _bot;
|
const auto bot = _bot;
|
||||||
const auto weak = _context.controller;
|
const auto weak = _context.controller;
|
||||||
|
|
|
@ -263,6 +263,8 @@ private:
|
||||||
void botSharePhone(Fn<void(bool shared)> callback) override;
|
void botSharePhone(Fn<void(bool shared)> callback) override;
|
||||||
void botInvokeCustomMethod(
|
void botInvokeCustomMethod(
|
||||||
Ui::BotWebView::CustomMethodRequest request) override;
|
Ui::BotWebView::CustomMethodRequest request) override;
|
||||||
|
void botSetEmojiStatus(
|
||||||
|
Ui::BotWebView::SetEmojiStatusRequest request) override;
|
||||||
void botOpenPrivacyPolicy() override;
|
void botOpenPrivacyPolicy() override;
|
||||||
void botClose() override;
|
void botClose() override;
|
||||||
|
|
||||||
|
@ -283,6 +285,8 @@ private:
|
||||||
QString _panelUrl;
|
QString _panelUrl;
|
||||||
std::unique_ptr<Ui::BotWebView::Panel> _panel;
|
std::unique_ptr<Ui::BotWebView::Panel> _panel;
|
||||||
|
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
static base::weak_ptr<WebViewInstance> PendingActivation;
|
static base::weak_ptr<WebViewInstance> PendingActivation;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1773,7 +1773,29 @@ void AddSummaryPremium(
|
||||||
}
|
}
|
||||||
|
|
||||||
Ui::AddSkip(content, descriptionPadding.bottom());
|
Ui::AddSkip(content, descriptionPadding.bottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Ui::RpWidget> MakeEmojiStatusPreview(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
not_null<DocumentData*> document) {
|
||||||
|
auto result = std::make_unique<Ui::RpWidget>(parent);
|
||||||
|
|
||||||
|
const auto raw = result.get();
|
||||||
|
const auto size = HistoryView::Sticker::EmojiSize();
|
||||||
|
const auto emoji = raw->lifetime().make_state<EmojiStatusTopBar>(
|
||||||
|
document,
|
||||||
|
[=](QRect r) { raw->update(std::move(r)); },
|
||||||
|
size);
|
||||||
|
raw->paintRequest() | rpl::start_with_next([=] {
|
||||||
|
auto p = QPainter(raw);
|
||||||
|
emoji->paint(p);
|
||||||
|
}, raw->lifetime());
|
||||||
|
|
||||||
|
raw->sizeValue() | rpl::start_with_next([=](QSize size) {
|
||||||
|
emoji->setCenter(QPointF(size.width() / 2., size.height() / 2.));
|
||||||
|
}, raw->lifetime());
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "settings/settings_type.h"
|
#include "settings/settings_type.h"
|
||||||
|
|
||||||
|
class DocumentData;
|
||||||
enum class PremiumFeature;
|
enum class PremiumFeature;
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
|
@ -108,5 +109,13 @@ void AddSummaryPremium(
|
||||||
const QString &ref,
|
const QString &ref,
|
||||||
Fn<void(PremiumFeature)> buttonCallback);
|
Fn<void(PremiumFeature)> buttonCallback);
|
||||||
|
|
||||||
|
[[nodiscard]] std::unique_ptr<Ui::RpWidget> MakeEmojiStatusPreview(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
not_null<DocumentData*> document);
|
||||||
|
[[nodiscard]] std::unique_ptr<Ui::RpWidget> MakeEmojiSetStatusPreview(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
not_null<DocumentData*> document);
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|
||||||
|
|
|
@ -824,6 +824,8 @@ bool Panel::createWebview(const Webview::ThemeParams ¶ms) {
|
||||||
processHeaderColor(arguments);
|
processHeaderColor(arguments);
|
||||||
} else if (command == "web_app_set_bottom_bar_color") {
|
} else if (command == "web_app_set_bottom_bar_color") {
|
||||||
processBottomBarColor(arguments);
|
processBottomBarColor(arguments);
|
||||||
|
} else if (command == "web_app_set_emoji_status") {
|
||||||
|
processEmojiStatusRequest(arguments);
|
||||||
} else if (command == "share_score") {
|
} else if (command == "share_score") {
|
||||||
_delegate->botHandleMenuButton(MenuButton::ShareGame);
|
_delegate->botHandleMenuButton(MenuButton::ShareGame);
|
||||||
}
|
}
|
||||||
|
@ -963,6 +965,41 @@ void Panel::switchInlineQueryMessage(const QJsonObject &args) {
|
||||||
_delegate->botSwitchInlineQuery(types, query);
|
_delegate->botSwitchInlineQuery(types, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Panel::processEmojiStatusRequest(const QJsonObject &args) {
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
_delegate->botClose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto emojiId = args["custom_emoji_id"].toString().toULongLong();
|
||||||
|
const auto expirationDate = TimeId(base::SafeRound(
|
||||||
|
args["expiration_date"].toDouble()));
|
||||||
|
if (!emojiId) {
|
||||||
|
postEvent(
|
||||||
|
"emoji_status_failed",
|
||||||
|
"{ error: \"SUGGESTED_EMOJI_INVALID\" }");
|
||||||
|
return;
|
||||||
|
} else if (expirationDate < 0) {
|
||||||
|
postEvent(
|
||||||
|
"emoji_status_failed",
|
||||||
|
"{ error: \"EXPIRATION_DATE_INVALID\" }");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto callback = crl::guard(this, [=](QString error) {
|
||||||
|
if (error.isEmpty()) {
|
||||||
|
postEvent("emoji_status_set");
|
||||||
|
} else {
|
||||||
|
postEvent(
|
||||||
|
"emoji_status_failed",
|
||||||
|
u"{ error: \"%1\" }"_q.arg(error));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_delegate->botSetEmojiStatus({
|
||||||
|
.customEmojiId = emojiId,
|
||||||
|
.expirationDate = expirationDate,
|
||||||
|
.callback = std::move(callback),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void Panel::openTgLink(const QJsonObject &args) {
|
void Panel::openTgLink(const QJsonObject &args) {
|
||||||
if (args.isEmpty()) {
|
if (args.isEmpty()) {
|
||||||
LOG(("BotWebView Error: Bad arguments in 'web_app_open_tg_link'."));
|
LOG(("BotWebView Error: Bad arguments in 'web_app_open_tg_link'."));
|
||||||
|
|
|
@ -51,6 +51,12 @@ struct CustomMethodRequest {
|
||||||
Fn<void(CustomMethodResult)> callback;
|
Fn<void(CustomMethodResult)> callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SetEmojiStatusRequest {
|
||||||
|
uint64 customEmojiId = 0;
|
||||||
|
TimeId expirationDate = 0;
|
||||||
|
Fn<void(QString)> callback;
|
||||||
|
};
|
||||||
|
|
||||||
class Delegate {
|
class Delegate {
|
||||||
public:
|
public:
|
||||||
virtual Webview::ThemeParams botThemeParams() = 0;
|
virtual Webview::ThemeParams botThemeParams() = 0;
|
||||||
|
@ -67,6 +73,7 @@ public:
|
||||||
virtual void botAllowWriteAccess(Fn<void(bool allowed)> callback) = 0;
|
virtual void botAllowWriteAccess(Fn<void(bool allowed)> callback) = 0;
|
||||||
virtual void botSharePhone(Fn<void(bool shared)> callback) = 0;
|
virtual void botSharePhone(Fn<void(bool shared)> callback) = 0;
|
||||||
virtual void botInvokeCustomMethod(CustomMethodRequest request) = 0;
|
virtual void botInvokeCustomMethod(CustomMethodRequest request) = 0;
|
||||||
|
virtual void botSetEmojiStatus(SetEmojiStatusRequest request) = 0;
|
||||||
virtual void botOpenPrivacyPolicy() = 0;
|
virtual void botOpenPrivacyPolicy() = 0;
|
||||||
virtual void botClose() = 0;
|
virtual void botClose() = 0;
|
||||||
};
|
};
|
||||||
|
@ -123,6 +130,8 @@ private:
|
||||||
void setTitle(rpl::producer<QString> title);
|
void setTitle(rpl::producer<QString> title);
|
||||||
void sendDataMessage(const QJsonObject &args);
|
void sendDataMessage(const QJsonObject &args);
|
||||||
void switchInlineQueryMessage(const QJsonObject &args);
|
void switchInlineQueryMessage(const QJsonObject &args);
|
||||||
|
void processEmojiStatusRequest(const QJsonObject &args);
|
||||||
|
void processEmojiStatusAccessRequest();
|
||||||
void processButtonMessage(
|
void processButtonMessage(
|
||||||
std::unique_ptr<Button> &button,
|
std::unique_ptr<Button> &button,
|
||||||
const QJsonObject &args);
|
const QJsonObject &args);
|
||||||
|
|
|
@ -1155,3 +1155,26 @@ msgSelectionCheck: RoundCheckbox(defaultPeerListCheck) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sponsoredMessageBarMaxHeight: 156px;
|
sponsoredMessageBarMaxHeight: 156px;
|
||||||
|
|
||||||
|
botEmojiStatusPreviewHeight: 148px;
|
||||||
|
botEmojiStatusTitle: FlatLabel(boxTitle) {
|
||||||
|
style: TextStyle(defaultTextStyle) {
|
||||||
|
font: font(16px semibold);
|
||||||
|
lineHeight: 20px;
|
||||||
|
}
|
||||||
|
minWidth: 256px;
|
||||||
|
maxHeight: 0px;
|
||||||
|
align: align(top);
|
||||||
|
}
|
||||||
|
botEmojiStatusText: FlatLabel(defaultFlatLabel) {
|
||||||
|
style: boxTextStyle;
|
||||||
|
minWidth: 256px;
|
||||||
|
maxHeight: 0px;
|
||||||
|
align: align(top);
|
||||||
|
}
|
||||||
|
botEmojiStatusUserpic: UserpicButton(defaultUserpicButton) {
|
||||||
|
size: size(chatGiveawayPeerSize, chatGiveawayPeerSize);
|
||||||
|
photoSize: chatGiveawayPeerSize;
|
||||||
|
}
|
||||||
|
botEmojiStatusName: FlatLabel(defaultFlatLabel) {
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue