From d1907083edc100c4df52d5a7dea8c229cca75f2a Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 23 May 2022 18:46:15 +0400 Subject: [PATCH] Add FileSizeLimitBox and pass "ref" to premium payment. --- Telegram/Resources/langs/lang.strings | 5 + Telegram/SourceFiles/apiwrap.cpp | 2 +- .../SourceFiles/boxes/add_contact_box.cpp | 299 +----------------- Telegram/SourceFiles/boxes/add_contact_box.h | 25 -- .../boxes/peers/edit_peer_type_box.cpp | 2 +- .../SourceFiles/boxes/premium_limits_box.cpp | 73 ++++- .../SourceFiles/boxes/premium_limits_box.h | 8 +- .../boxes/reactions_settings_box.cpp | 2 +- .../SourceFiles/boxes/sticker_preview_box.cpp | 2 +- .../SourceFiles/core/local_url_handlers.cpp | 6 +- .../data/stickers/data_stickers.cpp | 15 +- .../SourceFiles/history/history_widget.cpp | 6 +- .../view/history_view_replies_section.cpp | 6 +- .../view/history_view_scheduled_section.cpp | 6 +- .../SourceFiles/settings/settings_main.cpp | 7 +- .../SourceFiles/settings/settings_premium.cpp | 76 ++++- .../SourceFiles/settings/settings_premium.h | 6 +- .../SourceFiles/window/section_widget.cpp | 2 +- .../window/window_session_controller.cpp | 8 + .../window/window_session_controller.h | 5 + 20 files changed, 211 insertions(+), 350 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 2e29389e8..e0be2f086 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -223,6 +223,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_caption_limit_reached#one" = "You've reached the media caption limit. Please make the caption shorter by {count} character."; "lng_caption_limit_reached#other" = "You've reached the media caption limit. Please make the caption shorter by {count} characters."; +"lng_file_size_limit_title" = "File Too Large"; +"lng_file_size_limit" = "{total} Gb"; +"lng_file_size_limit1" = "The document can't be sent, because it is larger than {size}."; +"lng_file_size_limit2" = "You can double this limit to {size} per document by subscribing to **Telegram Premium**."; + "lng_limits_increase" = "Increase Limit"; "lng_sticker_premium_about" = "Unlock this sticker and more by subscribing to\nTelegram Premium."; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index b5d4f9349..eb2493c5e 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -453,7 +453,7 @@ void ApiWrap::sendMessageFail( : tr::lng_error_noforwards_group(tr::now) }, .duration = kJoinErrorDuration }); } else if (error.type() == qstr("PREMIUM_ACCOUNT_REQUIRED")) { - Settings::ShowPremium(&session()); + Settings::ShowPremium(&session(), "premium_stickers"); } if (const auto item = _session->data().message(itemId)) { Assert(randomId != 0); diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp index f9b263d92..75a74d0be 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.cpp +++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp @@ -207,48 +207,6 @@ void ShowAddParticipantsError( Ui::show(Ui::MakeInformBox(text), Ui::LayerOption::KeepOther); } -class RevokePublicLinkBox::Inner : public TWidget { -public: - Inner( - QWidget *parent, - not_null session, - Fn revokeCallback); - -protected: - void mouseMoveEvent(QMouseEvent *e) override; - void mousePressEvent(QMouseEvent *e) override; - void mouseReleaseEvent(QMouseEvent *e) override; - void paintEvent(QPaintEvent *e) override; - -private: - struct ChatRow { - ChatRow(not_null peer) : peer(peer) { - } - - not_null peer; - mutable std::shared_ptr userpic; - Ui::Text::String name, status; - }; - void paintChat(Painter &p, const ChatRow &row, bool selected) const; - void updateSelected(); - - const not_null _session; - MTP::Sender _api; - - PeerData *_selected = nullptr; - PeerData *_pressed = nullptr; - - std::vector _rows; - - int _rowsTop = 0; - int _rowHeight = 0; - int _revokeWidth = 0; - - Fn _revokeCallback; - mtpRequestId _revokeRequestId = 0; - -}; - AddContactBox::AddContactBox( QWidget*, not_null session) @@ -1243,9 +1201,7 @@ void SetupChannelBox::privacyChanged(Privacy value) { check(); }); Ui::show( - Box( - &_channel->session(), - callback), + Box(PublicLinksLimitBox, _navigation, callback), Ui::LayerOption::KeepOther); return; } @@ -1337,9 +1293,7 @@ void SetupChannelBox::showRevokePublicLinkBoxForEdit() { }; closeBox(); Ui::show( - Box( - &channel->session(), - callback), + Box(PublicLinksLimitBox, navigation, callback), Ui::LayerOption::KeepOther); } @@ -1505,252 +1459,3 @@ void EditNameBox::saveSelfFail(const QString &error) { _first->setFocus(); } } - -RevokePublicLinkBox::Inner::Inner( - QWidget *parent, - not_null session, - Fn revokeCallback) -: TWidget(parent) -, _session(session) -, _api(&_session->mtp()) -, _rowHeight(st::contactsPadding.top() - + st::contactsPhotoSize - + st::contactsPadding.bottom()) -, _revokeWidth(st::normalFont->width( - tr::lng_channels_too_much_public_revoke(tr::now))) -, _revokeCallback(std::move(revokeCallback)) { - setMouseTracking(true); - - resize(width(), 5 * _rowHeight); - - _api.request(MTPchannels_GetAdminedPublicChannels( - MTP_flags(0) - )).done([=](const MTPmessages_Chats &result) { - const auto &chats = result.match([](const auto &data) { - return data.vchats().v; - }); - for (const auto &chat : chats) { - if (const auto peer = _session->data().processChat(chat)) { - if (!peer->isChannel() || peer->userName().isEmpty()) { - continue; - } - - auto row = ChatRow(peer); - row.peer = peer; - row.name.setText( - st::contactsNameStyle, - peer->name, - Ui::NameTextOptions()); - row.status.setMarkedText( - st::defaultTextStyle, - _session->createInternalLink( - Ui::Text::Link(peer->userName()))); - _rows.push_back(std::move(row)); - } - } - resize(width(), _rows.size() * _rowHeight); - update(); - }).send(); -} - -RevokePublicLinkBox::RevokePublicLinkBox( - QWidget*, - not_null session, - Fn revokeCallback) -: _session(session) -, _aboutRevoke( - this, - tr::lng_channels_too_much_public_about(tr::now), - st::aboutRevokePublicLabel) -, _revokeCallback(std::move(revokeCallback)) { -} - -void RevokePublicLinkBox::prepare() { - _innerTop = st::boxPadding.top() - + _aboutRevoke->height() - + st::boxPadding.top(); - _inner = setInnerWidget(object_ptr(this, _session, [=] { - const auto callback = _revokeCallback; - closeBox(); - if (callback) { - callback(); - } - }), st::boxScroll, _innerTop); - - addButton(tr::lng_cancel(), [=] { closeBox(); }); - - _session->downloaderTaskFinished( - ) | rpl::start_with_next([=] { - update(); - }, lifetime()); - - _inner->resizeToWidth(st::boxWideWidth); - setDimensions(st::boxWideWidth, _innerTop + _inner->height()); -} - -void RevokePublicLinkBox::Inner::mouseMoveEvent(QMouseEvent *e) { - updateSelected(); -} - -void RevokePublicLinkBox::Inner::updateSelected() { - const auto point = mapFromGlobal(QCursor::pos()); - PeerData *selected = nullptr; - auto top = _rowsTop; - for (const auto &row : _rows) { - const auto revokeLink = style::rtlrect( - width() - - st::contactsPadding.right() - - st::contactsCheckPosition.x() - - _revokeWidth, - top - + st::contactsPadding.top() - + (st::contactsPhotoSize - st::normalFont->height) / 2, - _revokeWidth, - st::normalFont->height, - width()); - if (revokeLink.contains(point)) { - selected = row.peer; - break; - } - top += _rowHeight; - } - if (selected != _selected) { - _selected = selected; - setCursor((_selected || _pressed) - ? style::cur_pointer - : style::cur_default); - update(); - } -} - -void RevokePublicLinkBox::Inner::mousePressEvent(QMouseEvent *e) { - if (_pressed != _selected) { - _pressed = _selected; - update(); - } -} - -void RevokePublicLinkBox::Inner::mouseReleaseEvent(QMouseEvent *e) { - const auto pressed = base::take(_pressed); - setCursor((_selected || _pressed) - ? style::cur_pointer - : style::cur_default); - if (pressed && pressed == _selected) { - const auto textMethod = pressed->isMegagroup() - ? tr::lng_channels_too_much_public_revoke_confirm_group - : tr::lng_channels_too_much_public_revoke_confirm_channel; - const auto text = textMethod( - tr::now, - lt_link, - _session->createInternalLink(pressed->userName()), - lt_group, - pressed->name); - const auto confirmText = tr::lng_channels_too_much_public_revoke( - tr::now); - auto callback = crl::guard(this, [=](Fn &&close) { - if (_revokeRequestId) { - return; - } - _revokeRequestId = _api.request(MTPchannels_UpdateUsername( - pressed->asChannel()->inputChannel, - MTP_string() - )).done([=, close = std::move(close)] { - close(); - if (const auto callback = _revokeCallback) { - callback(); - } - }).send(); - }); - Ui::show( - Ui::MakeConfirmBox({ - .text = text, - .confirmed = std::move(callback), - .confirmText = confirmText, - }), - Ui::LayerOption::KeepOther); - } -} - -void RevokePublicLinkBox::Inner::paintEvent(QPaintEvent *e) { - Painter p(this); - p.translate(0, _rowsTop); - for (const auto &row : _rows) { - paintChat(p, row, (row.peer == _selected)); - p.translate(0, _rowHeight); - } -} - -void RevokePublicLinkBox::resizeEvent(QResizeEvent *e) { - BoxContent::resizeEvent(e); - - _aboutRevoke->moveToLeft(st::boxPadding.left(), st::boxPadding.top()); -} - -void RevokePublicLinkBox::Inner::paintChat( - Painter &p, - const ChatRow &row, - bool selected) const { - const auto peer = row.peer; - peer->paintUserpicLeft( - p, - row.userpic, - st::contactsPadding.left(), - st::contactsPadding.top(), - width(), - st::contactsPhotoSize); - - p.setPen(st::contactsNameFg); - - const auto namex = st::contactsPadding.left() - + st::contactsPhotoSize - + st::contactsPadding.left(); - auto namew = width() - - namex - - st::contactsPadding.right() - - (_revokeWidth + st::contactsCheckPosition.x() * 2); - - const auto badgeStyle = Ui::PeerBadgeStyle{ - &st::dialogsVerifiedIcon, - nullptr, // premium - &st::attentionButtonFg - }; - namew -= Ui::DrawPeerBadgeGetWidth( - peer, - p, - QRect( - namex, - st::contactsPadding.top() + st::contactsNameTop, - row.name.maxWidth(), - st::contactsNameStyle.font->height), - namew, - width(), - badgeStyle); - row.name.drawLeftElided( - p, - namex, - st::contactsPadding.top() + st::contactsNameTop, - namew, - width()); - - p.setFont(selected ? st::linkOverFont : st::linkFont); - p.setPen(selected - ? st::defaultLinkButton.overColor - : st::defaultLinkButton.color); - p.drawTextRight( - st::contactsPadding.right() + st::contactsCheckPosition.x(), - st::contactsPadding.top() - + (st::contactsPhotoSize - st::normalFont->height) / 2, - width(), - tr::lng_channels_too_much_public_revoke(tr::now), - _revokeWidth); - - p.setPen(st::contactsStatusFg); - p.setTextPalette(st::revokePublicLinkStatusPalette); - row.status.drawLeftElided( - p, - namex, - st::contactsPadding.top() + st::contactsStatusTop, - namew, - width()); - p.restoreTextPalette(); -} diff --git a/Telegram/SourceFiles/boxes/add_contact_box.h b/Telegram/SourceFiles/boxes/add_contact_box.h index 35bd39bf2..4e7665eca 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.h +++ b/Telegram/SourceFiles/boxes/add_contact_box.h @@ -249,28 +249,3 @@ private: QString _sentName; }; - -class RevokePublicLinkBox final : public Ui::BoxContent { -public: - RevokePublicLinkBox( - QWidget*, - not_null session, - Fn revokeCallback); - -protected: - void prepare() override; - - void resizeEvent(QResizeEvent *e) override; - -private: - const not_null _session; - - object_ptr _aboutRevoke; - - class Inner; - QPointer _inner; - - int _innerTop = 0; - Fn _revokeCallback; - -}; diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp index 06ab6117d..7609d14f7 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp @@ -579,7 +579,7 @@ void Controller::askUsernameRevoke() { checkUsernameAvailability(); }); _show->showBox( - Box(PublicLinksLimitBox, _navigation), + Box(PublicLinksLimitBox, _navigation, revokeCallback), Ui::LayerOption::KeepOther); } diff --git a/Telegram/SourceFiles/boxes/premium_limits_box.cpp b/Telegram/SourceFiles/boxes/premium_limits_box.cpp index 5cf831940..5b91aaf2f 100644 --- a/Telegram/SourceFiles/boxes/premium_limits_box.cpp +++ b/Telegram/SourceFiles/boxes/premium_limits_box.cpp @@ -394,6 +394,7 @@ void SimpleLimitBox( not_null session, rpl::producer title, rpl::producer text, + const QString &refAddition, const InfographicDescriptor &descriptor, bool premium, bool fixed = false) { @@ -433,7 +434,7 @@ void SimpleLimitBox( }); } else { box->addButton(tr::lng_limits_increase(), [=] { - Settings::ShowPremium(session); + Settings::ShowPremium(session, LimitsPremiumRef(refAddition)); }); } @@ -450,6 +451,7 @@ void SimpleLimitBox( void SimplePinsLimitBox( not_null box, not_null session, + const QString &refAddition, const QString &keyDefault, int limitDefault, const QString &keyPremium, @@ -480,6 +482,7 @@ void SimplePinsLimitBox( session, tr::lng_filter_pin_limit_title(), std::move(text), + refAddition, { defaultLimit, defaultLimit, premiumLimit, &st::premiumIconPins }, premium); } @@ -514,6 +517,7 @@ void ChannelsLimitBox( session, tr::lng_channels_limit_title(), std::move(text), + "channels", { defaultLimit, defaultLimit, premiumLimit, &st::premiumIconGroups }, premium, true); @@ -564,7 +568,7 @@ void ChannelsLimitBox( }); } else { box->addButton(tr::lng_limits_increase(), [=] { - Settings::ShowPremium(session); + Settings::ShowPremium(session, LimitsPremiumRef("channels")); }); } }, box->lifetime()); @@ -572,7 +576,8 @@ void ChannelsLimitBox( void PublicLinksLimitBox( not_null box, - not_null navigation) { + not_null navigation, + Fn retry) { const auto session = &navigation->session(); const auto premium = session->premium(); @@ -605,6 +610,7 @@ void PublicLinksLimitBox( session, tr::lng_links_limit_title(), std::move(text), + "channels_public", { defaultLimit, defaultLimit, premiumLimit, &st::premiumIconLinks }, premium, true); @@ -616,7 +622,7 @@ void PublicLinksLimitBox( const auto delegate = box->lifetime().make_state(); const auto controller = box->lifetime().make_state( navigation, - crl::guard(box, [=] { box->closeBox(); })); + crl::guard(box, [=] { box->closeBox(); retry(); })); const auto content = box->addRow( object_ptr(box, controller), @@ -672,6 +678,7 @@ void FilterChatsLimitBox( session, tr::lng_filter_chats_limit_title(), std::move(text), + "dialog_filters_chats", { defaultLimit, defaultLimit, premiumLimit, &st::premiumIconChats }, premium); } @@ -711,6 +718,7 @@ void FiltersLimitBox( session, tr::lng_filters_limit_title(), std::move(text), + "dialog_filters", { defaultLimit, defaultLimit, premiumLimit, &st::premiumIconFolders }, premium); } @@ -721,6 +729,7 @@ void FilterPinsLimitBox( SimplePinsLimitBox( box, session, + "dialog_filters_pinned", "dialog_filters_chats_limit_default", 100, "dialog_filters_chats_limit_premium", @@ -733,9 +742,10 @@ void FolderPinsLimitBox( SimplePinsLimitBox( box, session, - "dialog_filters_chats_limit_default", + "dialogs_folder_pinned", + "dialogs_folder_pinned_limit_default", 100, - "dialog_filters_chats_limit_premium", + "dialogs_folder_pinned_limit_premium", 200); } @@ -745,6 +755,7 @@ void PinsLimitBox( SimplePinsLimitBox( box, session, + "dialog_pinned", "dialogs_pinned_limit_default", 5, "dialogs_pinned_limit_premium", @@ -783,6 +794,7 @@ void CaptionLimitBox( session, tr::lng_caption_limit_title(), std::move(text), + "caption_length", { defaultLimit, defaultLimit, premiumLimit, &st::premiumIconChats }, premium); } @@ -806,6 +818,55 @@ void CaptionLimitReachedBox( } } +void FileSizeLimitBox( + not_null box, + not_null session) { + const auto premium = session->premium(); + + const auto defaultLimit = Limit( + session, + "upload_max_fileparts_default", + 4000); + const auto premiumLimit = Limit( + session, + "upload_max_fileparts_premium", + 8000); + + const auto defaultGb = (defaultLimit + 999) / 2000; + const auto premiumGb = (premiumLimit + 999) / 2000; + const auto gb = [](int count) { + return tr::lng_file_size_limit( + tr::now, + lt_total, + QString::number(count)); + }; + + auto text = rpl::combine( + tr::lng_file_size_limit1( + lt_size, + rpl::single(Ui::Text::Bold(gb(defaultGb))), + Ui::Text::RichLangValue), + tr::lng_file_size_limit2( + lt_size, + rpl::single(Ui::Text::Bold(gb(premiumGb))), + Ui::Text::RichLangValue) + ) | rpl::map([](TextWithEntities &&a, TextWithEntities &&b) { + return a.append(QChar(' ')).append(std::move(b)); + }); + + SimpleLimitBox( + box, + session, + tr::lng_file_size_limit_title(), + std::move(text), + "upload_max_fileparts", + { defaultGb, defaultGb, premiumGb, &st::premiumIconFiles }, + premium); +} + +QString LimitsPremiumRef(const QString &addition) { + return "double_limits__" + addition; +} int AppConfigLimit( not_null session, diff --git a/Telegram/SourceFiles/boxes/premium_limits_box.h b/Telegram/SourceFiles/boxes/premium_limits_box.h index 80fad40d2..9c19c19b4 100644 --- a/Telegram/SourceFiles/boxes/premium_limits_box.h +++ b/Telegram/SourceFiles/boxes/premium_limits_box.h @@ -22,7 +22,8 @@ void ChannelsLimitBox( not_null session); void PublicLinksLimitBox( not_null box, - not_null navigation); + not_null navigation, + Fn retry); void FilterChatsLimitBox( not_null box, not_null session); @@ -45,6 +46,11 @@ void CaptionLimitReachedBox( not_null box, not_null session, int remove); +void FileSizeLimitBox( + not_null box, + not_null session); + +[[nodiscard]] QString LimitsPremiumRef(const QString &addition); [[nodiscard]] int AppConfigLimit( not_null session, diff --git a/Telegram/SourceFiles/boxes/reactions_settings_box.cpp b/Telegram/SourceFiles/boxes/reactions_settings_box.cpp index 22e28a108..1bae05cd6 100644 --- a/Telegram/SourceFiles/boxes/reactions_settings_box.cpp +++ b/Telegram/SourceFiles/boxes/reactions_settings_box.cpp @@ -448,7 +448,7 @@ void ReactionsSettingsBox( button->setClickedCallback([=, emoji = r.emoji] { if (premium && !controller->session().premium()) { - Settings::ShowPremium(&controller->session()); + Settings::ShowPremium(controller, "unique_reactions"); return; } checkButton(button); diff --git a/Telegram/SourceFiles/boxes/sticker_preview_box.cpp b/Telegram/SourceFiles/boxes/sticker_preview_box.cpp index c4a3ff33b..18a46219d 100644 --- a/Telegram/SourceFiles/boxes/sticker_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_preview_box.cpp @@ -203,7 +203,7 @@ void StickerBox( const auto width = size - buttonPadding.left() - buttonPadding.right(); auto button = CreateUnlockButton(box, width); button->setClickedCallback([=] { - controller->showSettings(Settings::PremiumId()); + Settings::ShowPremium(controller, "premium_stickers"); }); box->addButton(std::move(button)); } diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index fc46c094c..c7a2dafcb 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -748,8 +748,10 @@ bool ResolvePremiumOffer( const auto params = url_parse_params( match->captured(1).mid(1), qthelp::UrlParamNameTransform::ToLower); - const auto ref = params.value(qsl("ref")); - controller->showSettings(::Settings::PremiumId()); + const auto refAddition = params.value(qsl("ref")); + const auto ref = "deeplink" + + (refAddition.isEmpty() ? QString() : '_' + refAddition); + ::Settings::ShowPremium(controller, ref); controller->window().activate(); return true; } diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.cpp b/Telegram/SourceFiles/data/stickers/data_stickers.cpp index 40a71d8c6..e586416ec 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.cpp +++ b/Telegram/SourceFiles/data/stickers/data_stickers.cpp @@ -88,7 +88,8 @@ using SetFlag = StickersSetFlag; void MaybeShowPremiumToast( Window::SessionController *controller, - TextWithEntities text) { + TextWithEntities text, + const QString &ref) { if (!controller) { return; } @@ -99,7 +100,7 @@ void MaybeShowPremiumToast( const auto widget = QPointer( controller->window().widget()->bodyWidget()); const auto filter = [=](const auto ...) { - controller->showSettings(Settings::PremiumId()); + Settings::ShowPremium(controller, ref); return false; }; Ui::ShowMultilineToast({ @@ -322,7 +323,10 @@ void Stickers::addSavedGif( 400); if (_savedGifs.size() > limit) { _savedGifs.pop_back(); - MaybeShowPremiumToast(controller, SavedGifsToast(session)); + MaybeShowPremiumToast( + controller, + SavedGifsToast(session), + LimitsPremiumRef("saved_gifs")); } session->local().writeSavedGifs(); @@ -534,7 +538,10 @@ void Stickers::checkFavedLimit( } ++i; } - MaybeShowPremiumToast(controller, FaveStickersToast(session)); + MaybeShowPremiumToast( + controller, + FaveStickersToast(session), + LimitsPremiumRef("stickers_faved")); } void Stickers::pushFavedToFront( diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index a8b2d9b29..c8b23f841 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/send_files_box.h" #include "boxes/share_box.h" #include "boxes/edit_caption_box.h" +#include "boxes/premium_limits_box.h" #include "boxes/peers/edit_peer_permissions_box.h" // ShowAboutGigagroup. #include "boxes/peers/edit_peer_requests_box.h" #include "core/file_utilities.h" @@ -4969,12 +4970,15 @@ bool HistoryWidget::showSendingFilesError( tr::now, lt_name, list.errorData); - case Error::PremiumRequired: return u"premium.."_q; + case Error::PremiumRequired: return u"(premium)"_q; } return tr::lng_forward_send_files_cant(tr::now); }(); if (text.isEmpty()) { return false; + } else if (text == u"(premium)"_q) { + controller()->show(Box(FileSizeLimitBox, &session())); + return true; } Ui::ShowMultilineToast({ diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index e61b858f1..7bf458a96 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -42,6 +42,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/delete_messages_box.h" #include "boxes/edit_caption_box.h" #include "boxes/send_files_box.h" +#include "boxes/premium_limits_box.h" #include "window/window_adaptive.h" #include "window/window_session_controller.h" #include "window/window_peer_menu.h" @@ -940,12 +941,15 @@ bool RepliesWidget::showSendingFilesError( tr::now, lt_name, list.errorData); - case Error::PremiumRequired: return u"premium.."_q; + case Error::PremiumRequired: return u"(premium)"_q; } return tr::lng_forward_send_files_cant(tr::now); }(); if (text.isEmpty()) { return false; + } else if (text == u"(premium)"_q) { + controller()->show(Box(FileSizeLimitBox, &session())); + return true; } Ui::ShowMultilineToast({ diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index 959aab852..deb047f58 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/delete_messages_box.h" #include "boxes/edit_caption_box.h" #include "boxes/send_files_box.h" +#include "boxes/premium_limits_box.h" #include "window/window_adaptive.h" #include "window/window_session_controller.h" #include "window/window_peer_menu.h" @@ -560,12 +561,15 @@ bool ScheduledWidget::showSendingFilesError( tr::now, lt_name, list.errorData); - case Error::PremiumRequired: return u"premium.."_q; + case Error::PremiumRequired: return u"(premium)"_q; } return tr::lng_forward_send_files_cant(tr::now); }(); if (text.isEmpty()) { return false; + } else if (text == u"(premium)"_q) { + controller()->show(Box(FileSizeLimitBox, &session())); + return true; } Ui::ShowMultilineToast({ diff --git a/Telegram/SourceFiles/settings/settings_main.cpp b/Telegram/SourceFiles/settings/settings_main.cpp index 75beca50b..a6a982260 100644 --- a/Telegram/SourceFiles/settings/settings_main.cpp +++ b/Telegram/SourceFiles/settings/settings_main.cpp @@ -251,7 +251,12 @@ void SetupSections( std::move(label), st::settingsButton, std::move(descriptor) - )->addClickHandler([=] { showOther(type); }); + )->addClickHandler([=] { + if (type == PremiumId()) { + controller->setPremiumRef("settings"); + } + showOther(type); + }); }; if (controller->session().supportMode()) { SetupSupport(controller, container); diff --git a/Telegram/SourceFiles/settings/settings_premium.cpp b/Telegram/SourceFiles/settings/settings_premium.cpp index b85b13aed..c72721c52 100644 --- a/Telegram/SourceFiles/settings/settings_premium.cpp +++ b/Telegram/SourceFiles/settings/settings_premium.cpp @@ -30,6 +30,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_account.h" #include "main/main_app_config.h" #include "window/window_session_controller.h" +#include "base/unixtime.h" +#include "apiwrap.h" #include "styles/style_boxes.h" #include "styles/style_chat_helpers.h" #include "styles/style_info.h" @@ -138,6 +140,58 @@ struct Entry { }; } +void SendAppLog( + not_null session, + const QString &type, + const MTPJSONValue &data) { + const auto now = double(base::unixtime::now()) + + (QTime::currentTime().msec() / 1000.); + session->api().request(MTPhelp_SaveAppLog( + MTP_vector(1, MTP_inputAppEvent( + MTP_double(now), + MTP_string(type), + MTP_long(0), + data + )) + )).send(); +} + +[[nodiscard]] QString ResolveRef(const QString &ref) { + return ref.isEmpty() ? "settings" : ref; +} + +void SendScreenShow( + not_null controller, + const std::vector &order, + const QString &ref) { + auto list = QVector(); + list.reserve(order.size()); + for (const auto &element : order) { + list.push_back(MTP_jsonString(MTP_string(element))); + } + auto values = QVector{ + MTP_jsonObjectValue( + MTP_string("premium_promo_order"), + MTP_jsonArray(MTP_vector(std::move(list)))), + MTP_jsonObjectValue( + MTP_string("source"), + MTP_jsonString(MTP_string(ResolveRef(ref)))), + }; + const auto data = MTP_jsonObject( + MTP_vector(std::move(values))); + SendAppLog( + &controller->session(), + "premium.promo_screen_show", + data); +} + +void SendScreenAccept(not_null controller) { + SendAppLog( + &controller->session(), + "premium.promo_screen_accept", + MTP_jsonNull()); +} + class TopBar final : public Ui::RpWidget { public: TopBar(not_null parent); @@ -282,6 +336,7 @@ private: void setupContent(); const not_null _controller; + const QString _ref; base::unique_qptr> _back; base::unique_qptr _close; @@ -296,7 +351,8 @@ Premium::Premium( QWidget *parent, not_null controller) : Section(parent) -, _controller(controller) { +, _controller(controller) +, _ref(ResolveRef(controller->premiumRef())) { setupContent(); } @@ -400,6 +456,8 @@ void Premium::setupContent() { processEntry(entry); } } + + SendScreenShow(_controller, mtpOrder, _ref); } content->resizeToWidth(content->height()); @@ -530,7 +588,8 @@ QPointer Premium::createPinnedToBottom( Ui::Premium::ButtonGradientStops()); result->setClickedCallback([=] { - StartPremiumPayment(_controller, "settings"); + SendScreenAccept(_controller); + StartPremiumPayment(_controller, _ref); }); const auto &st = st::premiumPreviewBox.button; @@ -561,22 +620,29 @@ Type PremiumId() { return Premium::Id(); } -void ShowPremium(not_null session) { +void ShowPremium(not_null session, const QString &ref) { const auto active = Core::App().activeWindow(); const auto controller = (active && active->isPrimary()) ? active->sessionController() : nullptr; if (controller && session == &controller->session()) { - controller->showSettings(Settings::PremiumId()); + ShowPremium(controller, ref); } else { for (const auto &controller : session->windows()) { if (controller->window().isPrimary()) { - controller->showSettings(Settings::PremiumId()); + ShowPremium(controller, ref); } } } } +void ShowPremium( + not_null controller, + const QString &ref) { + controller->setPremiumRef(ref); + controller->showSettings(Settings::PremiumId()); +} + void StartPremiumPayment( not_null controller, const QString &ref) { diff --git a/Telegram/SourceFiles/settings/settings_premium.h b/Telegram/SourceFiles/settings/settings_premium.h index 8973871d5..e640a2d3f 100644 --- a/Telegram/SourceFiles/settings/settings_premium.h +++ b/Telegram/SourceFiles/settings/settings_premium.h @@ -21,7 +21,11 @@ namespace Settings { [[nodiscard]] Type PremiumId(); -void ShowPremium(not_null<::Main::Session*> session); +void ShowPremium(not_null<::Main::Session*> session, const QString &ref); +void ShowPremium( + not_null controller, + const QString &ref); + void StartPremiumPayment( not_null controller, const QString &ref); diff --git a/Telegram/SourceFiles/window/section_widget.cpp b/Telegram/SourceFiles/window/section_widget.cpp index dc9b0dfe1..cfe4c924a 100644 --- a/Telegram/SourceFiles/window/section_widget.cpp +++ b/Telegram/SourceFiles/window/section_widget.cpp @@ -355,7 +355,7 @@ bool ShowReactPremiumError( if (i == end(list) || !i->premium) { return false; } - Settings::ShowPremium(&controller->session()); + Settings::ShowPremium(controller, "unique_reactions"); return true; } diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index f392f9419..f948a2554 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -1862,6 +1862,14 @@ HistoryView::PaintContext SessionController::preparePaintContext( args.clip); } +void SessionController::setPremiumRef(const QString &ref) { + _premiumRef = ref; +} + +QString SessionController::premiumRef() const { + return _premiumRef; +} + SessionController::~SessionController() { resetFakeUnreadWhileOpened(); } diff --git a/Telegram/SourceFiles/window/window_session_controller.h b/Telegram/SourceFiles/window/window_session_controller.h index c7957c436..8623ec7c9 100644 --- a/Telegram/SourceFiles/window/window_session_controller.h +++ b/Telegram/SourceFiles/window/window_session_controller.h @@ -503,6 +503,9 @@ public: return *_cachedReactionIconFactory; } + void setPremiumRef(const QString &ref); + [[nodiscard]] QString premiumRef() const; + rpl::lifetime &lifetime() { return _lifetime; } @@ -590,6 +593,8 @@ private: using ReactionIconFactory = HistoryView::Reactions::CachedIconFactory; std::unique_ptr _cachedReactionIconFactory; + QString _premiumRef; + rpl::lifetime _lifetime; };