From 3633c1920812b951bc7799795b549d893bc920b5 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 20 Feb 2025 12:22:20 +0400 Subject: [PATCH] Update API scheme, improve service messages. --- Telegram/Resources/langs/lang.strings | 11 ++- Telegram/SourceFiles/api/api_sending.cpp | 4 +- Telegram/SourceFiles/apiwrap.cpp | 2 +- .../data/data_chat_participant_status.cpp | 84 ------------------ .../data/data_chat_participant_status.h | 11 --- .../history/history_item_helpers.cpp | 88 +++++++++++++++++++ .../history/history_item_helpers.h | 19 ++++ .../SourceFiles/history/history_widget.cpp | 71 ++++++++++----- Telegram/SourceFiles/history/history_widget.h | 5 +- .../history/view/history_view_message.cpp | 85 ++++++++++++------ .../history/view/history_view_message.h | 1 + .../history/view/media/history_view_media.h | 13 +++ .../view/media/history_view_media_grouped.cpp | 9 ++ .../view/media/history_view_media_grouped.h | 1 + Telegram/SourceFiles/mtproto/scheme/api.tl | 4 +- 15 files changed, 253 insertions(+), 155 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 411b64a13..5b378b5d1 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2166,12 +2166,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_action_boost_apply#other" = "{from} boosted the group {count} times"; "lng_action_set_chat_intro" = "{from} added the message below for all empty chats. How?"; "lng_action_payment_refunded" = "{peer} refunded {amount}"; -"lng_action_paid_message_sent#one" = "You paid {count} Star to send a message"; -"lng_action_paid_message_sent#other" = "You paid {count} Stars to send a message"; +"lng_action_paid_message_sent#one" = "You paid {count} Star to {action}"; +"lng_action_paid_message_sent#other" = "You paid {count} Star to {action}"; +"lng_action_paid_message_group#one" = "{from} paid {count} Star to {action}"; +"lng_action_paid_message_group#other" = "{from} paid {count} Star to {action}"; +"lng_action_paid_message_one" = "send a message"; +"lng_action_paid_message_some#one" = "send {count} message"; +"lng_action_paid_message_some#other" = "send {count} messages"; "lng_action_paid_message_got#one" = "You received {count} Star from {name}"; "lng_action_paid_message_got#other" = "You received {count} Stars from {name}"; -"lng_action_paid_message_group#one" = "{from} paid {count} Star to send a message"; -"lng_action_paid_message_group#other" = "{from} paid {count} Stars to send a message"; "lng_similar_channels_title" = "Similar channels"; "lng_similar_channels_view_all" = "View all"; diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp index 5fe1a2df4..814b0a983 100644 --- a/Telegram/SourceFiles/api/api_sending.cpp +++ b/Telegram/SourceFiles/api/api_sending.cpp @@ -634,7 +634,9 @@ void SendConfirmedFile( .replyTo = file->to.replyTo, .date = NewMessageDate(file->to.options), .shortcutId = file->to.options.shortcutId, - .starsPaid = file->to.options.starsApproved, + .starsPaid = std::min( + history->peer->starsPerMessageChecked(), + file->to.options.starsApproved), .postAuthor = NewMessagePostAuthor(action), .groupedId = groupId, .effectId = file->to.options.effectId, diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 1509fd8de..dad5a8730 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -4481,7 +4481,7 @@ void ApiWrap::sendAlbumIfReady(not_null album) { const auto replyTo = sample->replyTo(); const auto sendAs = album->options.sendAs; const auto starsPaid = std::min( - history->peer->starsPerMessageChecked(), + history->peer->starsPerMessageChecked() * int(medias.size()), album->options.starsApproved); if (starsPaid) { album->options.starsApproved -= starsPaid; diff --git a/Telegram/SourceFiles/data/data_chat_participant_status.cpp b/Telegram/SourceFiles/data/data_chat_participant_status.cpp index 14ae85c26..29b9cb451 100644 --- a/Telegram/SourceFiles/data/data_chat_participant_status.cpp +++ b/Telegram/SourceFiles/data/data_chat_participant_status.cpp @@ -17,14 +17,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "lang/lang_keys.h" #include "main/main_session.h" -#include "settings/settings_credits_graphics.h" -#include "storage/storage_account.h" #include "ui/boxes/confirm_box.h" #include "ui/chat/attach/attach_prepare.h" #include "ui/layers/generic_box.h" #include "ui/text/text_utilities.h" #include "ui/toast/toast.h" -#include "ui/widgets/checkbox.h" #include "window/window_session_controller.h" #include "styles/style_widgets.h" @@ -431,85 +428,4 @@ void ShowSendErrorToast( }); } -void ShowSendPaidConfirm( - not_null navigation, - not_null peer, - SendError error, - Fn confirmed) { - return ShowSendPaidConfirm(navigation->uiShow(), peer, error, confirmed); -} - -void ShowSendPaidConfirm( - std::shared_ptr show, - not_null peer, - Data::SendError error, - Fn confirmed) { - const auto check = [=] { - const auto required = error.paidStars; - if (!required) { - return; - } - const auto done = [=](Settings::SmallBalanceResult result) { - if (result == Settings::SmallBalanceResult::Success - || result == Settings::SmallBalanceResult::Already) { - confirmed(); - } - }; - Settings::MaybeRequestBalanceIncrease( - show, - required, - Settings::SmallBalanceForMessage{ .recipientId = peer->id }, - done); - }; - - const auto session = &peer->session(); - if (session->local().isPeerTrustedPayForMessage(peer->id)) { - check(); - return; - } - const auto messages = error.paidMessages; - const auto stars = error.paidStars; - show->showBox(Box([=](not_null box) { - const auto trust = std::make_shared>(); - const auto proceed = [=](Fn close) { - if ((*trust)->checked()) { - session->local().markPeerTrustedPayForMessage(peer->id); - } - check(); - close(); - }; - Ui::ConfirmBox(box, { - .text = tr::lng_payment_confirm_text( - tr::now, - lt_count, - stars / messages, - lt_name, - Ui::Text::Bold(peer->shortName()), - Ui::Text::RichLangValue).append(' ').append( - tr::lng_payment_confirm_sure( - tr::now, - lt_count, - messages, - lt_amount, - tr::lng_payment_confirm_amount( - tr::now, - lt_count, - stars, - Ui::Text::RichLangValue), - Ui::Text::RichLangValue)), - .confirmed = proceed, - .confirmText = tr::lng_payment_confirm_button( - lt_count, - rpl::single(messages * 1.)), - .title = tr::lng_payment_confirm_title(), - }); - const auto skip = st::defaultCheckbox.margin.top(); - *trust = box->addRow( - object_ptr( - box, - tr::lng_payment_confirm_dont_ask(tr::now)), - st::boxRowPadding + QMargins(0, skip, 0, skip)); - })); -} - } // namespace Data diff --git a/Telegram/SourceFiles/data/data_chat_participant_status.h b/Telegram/SourceFiles/data/data_chat_participant_status.h index 8de7df333..bfa24fb86 100644 --- a/Telegram/SourceFiles/data/data_chat_participant_status.h +++ b/Telegram/SourceFiles/data/data_chat_participant_status.h @@ -244,15 +244,4 @@ void ShowSendErrorToast( not_null peer, SendError error); -void ShowSendPaidConfirm( - not_null navigation, - not_null peer, - SendError error, - Fn confirmed); -void ShowSendPaidConfirm( - std::shared_ptr show, - not_null peer, - SendError error, - Fn confirmed); - } // namespace Data diff --git a/Telegram/SourceFiles/history/history_item_helpers.cpp b/Telegram/SourceFiles/history/history_item_helpers.cpp index 5e8c8d779..2420807c0 100644 --- a/Telegram/SourceFiles/history/history_item_helpers.cpp +++ b/Telegram/SourceFiles/history/history_item_helpers.cpp @@ -38,10 +38,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/unixtime.h" #include "core/application.h" #include "core/click_handler_types.h" // ClickHandlerContext. +#include "settings/settings_credits_graphics.h" +#include "storage/storage_account.h" #include "ui/boxes/confirm_box.h" #include "ui/text/format_values.h" #include "ui/text/text_utilities.h" #include "ui/toast/toast.h" +#include "ui/widgets/checkbox.h" #include "ui/item_text_options.h" #include "lang/lang_keys.h" @@ -242,6 +245,91 @@ object_ptr MakeSendErrorBox( }); } +void ShowSendPaidConfirm( + not_null navigation, + not_null peer, + SendPaymentDetails details, + Fn confirmed) { + return ShowSendPaidConfirm( + navigation->uiShow(), + peer, + details, + confirmed); +} + +void ShowSendPaidConfirm( + std::shared_ptr show, + not_null peer, + SendPaymentDetails details, + Fn confirmed) { + const auto check = [=] { + const auto required = details.stars; + if (!required) { + return; + } + const auto done = [=](Settings::SmallBalanceResult result) { + if (result == Settings::SmallBalanceResult::Success + || result == Settings::SmallBalanceResult::Already) { + confirmed(); + } + }; + Settings::MaybeRequestBalanceIncrease( + show, + required, + Settings::SmallBalanceForMessage{ .recipientId = peer->id }, + done); + }; + + const auto session = &peer->session(); + if (session->local().isPeerTrustedPayForMessage(peer->id)) { + check(); + return; + } + const auto messages = details.messages; + const auto stars = details.stars; + show->showBox(Box([=](not_null box) { + const auto trust = std::make_shared>(); + const auto proceed = [=](Fn close) { + if ((*trust)->checked()) { + session->local().markPeerTrustedPayForMessage(peer->id); + } + check(); + close(); + }; + Ui::ConfirmBox(box, { + .text = tr::lng_payment_confirm_text( + tr::now, + lt_count, + stars / messages, + lt_name, + Ui::Text::Bold(peer->shortName()), + Ui::Text::RichLangValue).append(' ').append( + tr::lng_payment_confirm_sure( + tr::now, + lt_count, + messages, + lt_amount, + tr::lng_payment_confirm_amount( + tr::now, + lt_count, + stars, + Ui::Text::RichLangValue), + Ui::Text::RichLangValue)), + .confirmed = proceed, + .confirmText = tr::lng_payment_confirm_button( + lt_count, + rpl::single(messages * 1.)), + .title = tr::lng_payment_confirm_title(), + }); + const auto skip = st::defaultCheckbox.margin.top(); + *trust = box->addRow( + object_ptr( + box, + tr::lng_payment_confirm_dont_ask(tr::now)), + st::boxRowPadding + QMargins(0, skip, 0, skip)); + })); +} + void RequestDependentMessageItem( not_null item, PeerId peerId, diff --git a/Telegram/SourceFiles/history/history_item_helpers.h b/Telegram/SourceFiles/history/history_item_helpers.h index e462d3bd9..8265c21b9 100644 --- a/Telegram/SourceFiles/history/history_item_helpers.h +++ b/Telegram/SourceFiles/history/history_item_helpers.h @@ -16,6 +16,10 @@ struct SendOptions; struct SendAction; } // namespace Api +namespace ChatHelpers { +class Show; +} // namespace ChatHelpers + namespace Data { class Story; class Thread; @@ -31,6 +35,10 @@ namespace Ui { class BoxContent; } // namespace Ui +namespace Window { +class SessionNavigation; +} // namespace Window + struct PreparedServiceText { TextWithEntities text; std::vector links; @@ -135,6 +143,17 @@ struct SendPaymentDetails { not_null peer, int messagesCount); +void ShowSendPaidConfirm( + not_null navigation, + not_null peer, + SendPaymentDetails details, + Fn confirmed); +void ShowSendPaidConfirm( + std::shared_ptr show, + not_null peer, + SendPaymentDetails details, + Fn confirmed); + [[nodiscard]] Data::SendErrorWithThread GetErrorForSending( const std::vector> &threads, SendingErrorRequest request); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index f2095aac4..bf6c33cc5 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -225,6 +225,14 @@ const auto kPsaAboutPrefix = "cloud_lng_about_psa_"; } // namespace +struct HistoryWidget::SendingFiles { + Ui::PreparedList list; + Ui::SendFilesWay way; + TextWithTags caption; + Api::SendOptions options; + bool ctrlShiftEnter = false; +}; + HistoryWidget::HistoryWidget( QWidget *parent, not_null controller) @@ -5896,8 +5904,7 @@ bool HistoryWidget::showSendMessageError( const TextWithTags &textWithTags, bool ignoreSlowmodeCountdown, Fn resend, - int starsApproved, - bool mediaMessage) { + int starsApproved) { if (!_canSendMessages) { return false; } @@ -5908,8 +5915,7 @@ bool HistoryWidget::showSendMessageError( .text = &textWithTags, .ignoreSlowmodeCountdown = ignoreSlowmodeCountdown, }; - request.messagesCount = ComputeSendingMessagesCount(_history, request) - + (mediaMessage ? 1 : 0); + request.messagesCount = ComputeSendingMessagesCount(_history, request); const auto error = GetErrorForSending(_peer, request); if (error) { Data::ShowSendErrorToast(controller(), _peer, error); @@ -5926,14 +5932,14 @@ bool HistoryWidget::checkSendPayment( const auto details = ComputePaymentDetails(_peer, messagesCount); if (!details) { _resendOnFullUpdated = [=] { resend(starsApproved); }; - return true; - } else if (const auto stars = details->stars) { - Data::ShowSendPaidConfirm(controller(), _peer, error, [=] { + return false; + } else if (const auto stars = details->stars; stars > starsApproved) { + ShowSendPaidConfirm(controller(), _peer, *details, [=] { resend(stars); }); - return true; + return false; } - return false; + return true; } bool HistoryWidget::confirmSendingFiles(const QStringList &files) { @@ -6019,28 +6025,53 @@ bool HistoryWidget::confirmSendingFiles( } void HistoryWidget::sendingFilesConfirmed( - Ui::PreparedList &&list, - Ui::SendFilesWay way, - TextWithTags &&caption, - Api::SendOptions options, - bool ctrlShiftEnter) { + Ui::PreparedList &&list, + Ui::SendFilesWay way, + TextWithTags &&caption, + Api::SendOptions options, + bool ctrlShiftEnter) { Expects(list.filesToProcess.empty()); const auto compress = way.sendImagesAsPhotos(); if (showSendingFilesError(list, compress)) { return; } + + sendingFilesConfirmed(std::make_shared(SendingFiles{ + .list = std::move(list), + .way = way, + .caption = std::move(caption), + .options = options, + .ctrlShiftEnter = ctrlShiftEnter, + })); +} + +void HistoryWidget::sendingFilesConfirmed( + std::shared_ptr args) { + const auto withPaymentApproved = [=](int approved) { + args->options.starsApproved = approved; + sendingFilesConfirmed(args); + }; + const auto checked = checkSendPayment( + args->list.files.size(), + args->options.starsApproved, + withPaymentApproved); + if (!checked) { + return; + } + auto groups = DivideByGroups( - std::move(list), - way, + std::move(args->list), + args->way, _peer->slowmodeApplied()); + const auto compress = args->way.sendImagesAsPhotos(); const auto type = compress ? SendMediaType::Photo : SendMediaType::File; - auto action = prepareSendAction(options); + auto action = prepareSendAction(args->options); action.clearDraft = false; if ((groups.size() != 1 || !groups.front().sentWithCaption()) - && !caption.text.isEmpty()) { + && !args->caption.text.isEmpty()) { auto message = Api::MessageToSend(action); - message.textWithTags = base::take(caption); + message.textWithTags = base::take(args->caption); session().api().sendMessage(std::move(message)); } for (auto &group : groups) { @@ -6050,7 +6081,7 @@ void HistoryWidget::sendingFilesConfirmed( session().api().sendFiles( std::move(group.list), type, - base::take(caption), + base::take(args->caption), album, action); } diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 96abc7e1e..425419530 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -320,6 +320,7 @@ private: using TabbedPanel = ChatHelpers::TabbedPanel; using TabbedSelector = ChatHelpers::TabbedSelector; using VoiceToSend = HistoryView::Controls::VoiceToSend; + struct SendingFiles; enum ScrollChangeType { ScrollChangeNone, @@ -472,8 +473,7 @@ private: const TextWithTags &textWithTags, bool ignoreSlowmodeCountdown, Fn resend = nullptr, - int starsApproved = 0, - bool mediaMessage = false); + int starsApproved = 0); bool checkSendPayment( int messagesCount, int starsApproved, @@ -485,6 +485,7 @@ private: TextWithTags &&caption, Api::SendOptions options, bool ctrlShiftEnter); + void sendingFilesConfirmed(std::shared_ptr args); void uploadFile(const QByteArray &fileContent, SendMediaType type); void itemRemoved(not_null item); diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 1dc5c6cae..9e28b6188 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -431,35 +431,7 @@ Message::Message( _rightAction->second->link = ReportSponsoredClickHandler(data); } } - if (const auto stars = data->starsPaid()) { - auto text = PreparedServiceText{ - .text = data->out() - ? tr::lng_action_paid_message_sent( - tr::now, - lt_count, - stars, - Ui::Text::WithEntities) - : history()->peer->isUser() - ? tr::lng_action_paid_message_got( - tr::now, - lt_count, - stars, - lt_name, - Ui::Text::Link(data->from()->shortName(), 1), - Ui::Text::WithEntities) - : tr::lng_action_paid_message_group( - tr::now, - lt_count, - stars, - lt_from, - Ui::Text::Link(data->from()->shortName(), 1), - Ui::Text::WithEntities), - }; - if (!data->out()) { - text.links.push_back(data->from()->createOpenLink()); - } - setServicePreMessage(std::move(text)); - } + initPaidInformation(); } Message::~Message() { @@ -470,6 +442,61 @@ Message::~Message() { } } +void Message::initPaidInformation() { + const auto item = data(); + const auto media = this->media(); + const auto mine = PaidInformation{ + .messages = 1, + .stars = item->starsPaid(), + }; + auto info = media ? media->paidInformation().value_or(mine) : mine; + if (!info) { + return; + } + const auto action = [&] { + return (info.messages == 1) + ? tr::lng_action_paid_message_one( + tr::now, + Ui::Text::WithEntities) + : tr::lng_action_paid_message_some( + tr::now, + lt_count, + info.messages, + Ui::Text::WithEntities); + }; + auto text = PreparedServiceText{ + .text = item->out() + ? tr::lng_action_paid_message_sent( + tr::now, + lt_count, + info.stars, + lt_action, + action(), + Ui::Text::WithEntities) + : history()->peer->isUser() + ? tr::lng_action_paid_message_got( + tr::now, + lt_count, + info.stars, + lt_name, + Ui::Text::Link(item->from()->shortName(), 1), + Ui::Text::WithEntities) + : tr::lng_action_paid_message_group( + tr::now, + lt_count, + info.stars, + lt_from, + Ui::Text::Link(item->from()->shortName(), 1), + lt_action, + action(), + Ui::Text::WithEntities), + }; + if (!item->out()) { + text.links.push_back(item ->from()->createOpenLink()); + } + setServicePreMessage(std::move(text)); +} + void Message::refreshRightBadge() { const auto item = data(); const auto text = [&] { diff --git a/Telegram/SourceFiles/history/view/history_view_message.h b/Telegram/SourceFiles/history/view/history_view_message.h index 735126d30..b33b29edc 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.h +++ b/Telegram/SourceFiles/history/view/history_view_message.h @@ -178,6 +178,7 @@ private: bool updateBottomInfo(); + void initPaidInformation(); void initLogEntryOriginal(); void initPsa(); void fromNameUpdated(int width) const; diff --git a/Telegram/SourceFiles/history/view/media/history_view_media.h b/Telegram/SourceFiles/history/view/media/history_view_media.h index 93c877b66..844f0465c 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media.h @@ -78,6 +78,15 @@ enum class MediaInBubbleState : uchar { TimeId duration, const QString &base); +struct PaidInformation { + int messages = 0; + int stars = 0; + + explicit operator bool() const { + return stars != 0; + } +}; + class Media : public Object, public base::has_weak_ptr { public: explicit Media(not_null parent) : _parent(parent) { @@ -121,6 +130,10 @@ public: [[nodiscard]] virtual bool allowsFastShare() const { return false; } + [[nodiscard]] virtual auto paidInformation() const + -> std::optional { + return {}; + } virtual void refreshParentId(not_null realParent) { } virtual void drawHighlight( diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp index 2b7d2cf99..60c14205a 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp @@ -867,6 +867,15 @@ QPoint GroupedMedia::resolveCustomInfoRightBottom() const { return QPoint(width() - skipx, height() - skipy); } +std::optional GroupedMedia::paidInformation() const { + auto result = PaidInformation(); + for (const auto &part : _parts) { + ++result.messages; + result.stars += part.item->starsPaid(); + } + return result; +} + bool GroupedMedia::enforceBubbleWidth() const { return _mode == Mode::Grid; } diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h index 459eb4b1c..24499a776 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h @@ -93,6 +93,7 @@ public: bool allowsFastShare() const override { return true; } + std::optional paidInformation() const override; bool customHighlight() const override { return true; } diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 69a98e922..5884d4d86 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -236,7 +236,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason; inputReportReasonIllegalDrugs#a8eb2be = ReportReason; inputReportReasonPersonalDetails#9ec7863d = ReportReason; -userFull#8555f3c2 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram bot_verification:flags2.12?BotVerification send_paid_messages_stars:flags2.14?long = UserFull; +userFull#d2234ea0 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram bot_verification:flags2.12?BotVerification send_paid_messages_stars:flags2.14?long = UserFull; contact#145ade0b user_id:long mutual:Bool = Contact; @@ -1496,8 +1496,6 @@ inputStorePaymentStarsTopup#dddd0f56 stars:long currency:string amount:long = In inputStorePaymentStarsGift#1d741ef7 user_id:InputUser stars:long currency:string amount:long = InputStorePaymentPurpose; inputStorePaymentStarsGiveaway#751f08fa flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true stars:long boost_peer:InputPeer additional_peers:flags.1?Vector countries_iso2:flags.2?Vector prize_description:flags.4?string random_id:long until_date:int currency:string amount:long users:int = InputStorePaymentPurpose; -premiumGiftOption#79c059f7 flags:# months:int currency:string amount:long bot_url:flags.1?string store_product:flags.0?string = PremiumGiftOption; - paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod; emojiStatusEmpty#2de11aae = EmojiStatus;