From 51213b499fd09164d44d0b70a7a6ca16a627a283 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 7 Jan 2025 14:52:25 +0400 Subject: [PATCH] Start showing gifts from stories. --- .../SourceFiles/boxes/gift_premium_box.cpp | 116 ++++---- Telegram/SourceFiles/boxes/gift_premium_box.h | 14 +- .../boxes/peers/edit_peer_color_box.cpp | 12 +- .../boxes/peers/edit_peer_invite_link.cpp | 3 +- .../boxes/peers/prepare_short_info_box.cpp | 24 +- .../boxes/peers/prepare_short_info_box.h | 9 + .../SourceFiles/boxes/premium_preview_box.cpp | 3 +- .../SourceFiles/boxes/sticker_set_box.cpp | 4 +- .../chat_helpers/compose/compose_show.cpp | 6 +- .../chat_helpers/compose/compose_show.h | 10 +- .../chat_helpers/emoji_list_widget.cpp | 3 +- .../chat_helpers/stickers_list_widget.cpp | 3 +- .../chat_helpers/tabbed_selector.cpp | 3 +- .../SourceFiles/core/local_url_handlers.cpp | 80 +++--- .../SourceFiles/core/local_url_handlers.h | 8 + .../data/data_chat_participant_status.cpp | 3 +- Telegram/SourceFiles/data/data_story.cpp | 4 + .../data/stickers/data_stickers.cpp | 3 +- .../history/history_item_helpers.cpp | 3 +- .../history_view_compose_controls.cpp | 3 +- .../inline_bots/bot_attach_web_view.cpp | 3 +- Telegram/SourceFiles/mainwidget.cpp | 1 + .../stories/media_stories_controller.cpp | 34 ++- .../media/stories/media_stories_controller.h | 3 + .../media/stories/media_stories_stealth.cpp | 3 +- .../media/view/media_view_overlay_widget.cpp | 3 +- Telegram/SourceFiles/menu/menu_send.cpp | 3 +- .../settings/business/settings_chat_intro.cpp | 4 +- .../settings/settings_credits_graphics.cpp | 250 +++++++++--------- .../settings/settings_credits_graphics.h | 11 +- .../SourceFiles/settings/settings_premium.cpp | 23 +- .../SourceFiles/settings/settings_premium.h | 9 +- 32 files changed, 347 insertions(+), 314 deletions(-) diff --git a/Telegram/SourceFiles/boxes/gift_premium_box.cpp b/Telegram/SourceFiles/boxes/gift_premium_box.cpp index 3b9cc1ecb..4bdc788e3 100644 --- a/Telegram/SourceFiles/boxes/gift_premium_box.cpp +++ b/Telegram/SourceFiles/boxes/gift_premium_box.cpp @@ -129,7 +129,7 @@ constexpr auto kRarityTooltipDuration = 3 * crl::time(1000); [[nodiscard]] object_ptr MakePeerTableValue( not_null parent, - not_null controller, + std::shared_ptr show, PeerId id, rpl::producer button = nullptr, Fn handler = nullptr) { @@ -139,7 +139,7 @@ constexpr auto kRarityTooltipDuration = 3 * crl::time(1000); const auto &st = st::giveawayGiftCodeUserpic; raw->resize(raw->width(), st.photoSize); - const auto peer = controller->session().data().peer(id); + const auto peer = show->session().data().peer(id); const auto userpic = Ui::CreateChild(raw, peer, st); const auto label = Ui::CreateChild( raw, @@ -182,15 +182,14 @@ constexpr auto kRarityTooltipDuration = 3 * crl::time(1000); label->setTextColorOverride(st::windowActiveTextFg->c); raw->setClickedCallback([=] { - controller->uiShow()->showBox(PrepareShortInfoBox(peer, controller)); + show->showBox(PrepareShortInfoBox(peer, show)); }); return result; } [[nodiscard]] object_ptr MakeHiddenPeerTableValue( - not_null parent, - not_null controller) { + not_null parent) { auto result = object_ptr(parent); const auto raw = result.data(); @@ -295,13 +294,13 @@ void AddTableRow( [[nodiscard]] object_ptr MakeStarGiftStarsValue( not_null parent, - not_null controller, + std::shared_ptr show, const Data::CreditsHistoryEntry &entry, Fn convertToStars) { auto result = object_ptr(parent); const auto raw = result.data(); - const auto session = &controller->session(); + const auto session = &show->session(); const auto makeContext = [session](Fn update) { return Core::MarkedTextContext{ .session = session, @@ -360,7 +359,6 @@ void AddTableRow( [[nodiscard]] object_ptr MakeVisibilityTableValue( not_null parent, - not_null controller, bool savedToProfile, Fn toggleVisibility) { auto result = object_ptr(parent); @@ -414,7 +412,6 @@ void AddTableRow( [[nodiscard]] object_ptr MakeNonUniqueStatusTableValue( not_null parent, - not_null controller, Fn startUpgrade) { auto result = object_ptr(parent); const auto raw = result.data(); @@ -482,7 +479,7 @@ not_null AddTableRow( void AddTableRow( not_null table, rpl::producer label, - not_null controller, + std::shared_ptr show, PeerId id) { if (!id) { return; @@ -490,13 +487,13 @@ void AddTableRow( AddTableRow( table, std::move(label), - MakePeerTableValue(table, controller, id), + MakePeerTableValue(table, show, id), st::giveawayGiftCodePeerMargin); } void AddTable( not_null container, - not_null controller, + std::shared_ptr show, const Api::GiftCode ¤t, bool skipReason) { auto table = container->add( @@ -508,14 +505,14 @@ void AddTable( AddTableRow( table, tr::lng_gift_link_label_from(), - controller, + show, current.from); } if (current.from && current.to) { AddTableRow( table, tr::lng_gift_link_label_to(), - controller, + show, current.to); } else if (current.from) { AddTableRow( @@ -547,10 +544,12 @@ void AddTable( ) | rpl::type_erased()) : tr::lng_gift_link_reason_chosen(Ui::Text::WithEntities))); reason->setClickHandlerFilter([=](const auto &...) { - controller->showPeerHistory( - current.from, - Window::SectionShow::Way::Forward, - current.giveawayId); + if (const auto window = show->resolveWindow()) { + window->showPeerHistory( + current.from, + Window::SectionShow::Way::Forward, + current.giveawayId); + } return false; }); } @@ -678,7 +677,8 @@ void GiftCodeBox( MakeLinkCopyIcon(box)), st::giveawayGiftCodeLinkMargin); - AddTable(box->verticalLayout(), controller, state->data.current(), false); + const auto show = controller->uiShow(); + AddTable(box->verticalLayout(), show, state->data.current(), false); auto shareLink = tr::lng_gift_link_also_send_link( ) | rpl::map([](const QString &text) { @@ -838,7 +838,8 @@ void GiftCodePendingBox( spoiler->show(); } - AddTable(box->verticalLayout(), controller, data, true); + const auto show = controller->uiShow(); + AddTable(box->verticalLayout(), show, data, true); box->addRow( object_ptr( @@ -1189,7 +1190,7 @@ void ResolveGiveawayInfo( } void AddStarGiftTable( - not_null controller, + std::shared_ptr show, not_null container, const Data::CreditsHistoryEntry &entry, Fn toggleVisibility, @@ -1201,7 +1202,7 @@ void AddStarGiftTable( st::giveawayGiftCodeTable), st::giveawayGiftCodeTableMargin); const auto peerId = PeerId(entry.barePeerId); - const auto session = &controller->session(); + const auto session = &show->session(); const auto unique = entry.uniqueGift.get(); const auto selfBareId = session->userPeerId().value; const auto giftToSelf = (peerId == session->userPeerId()) @@ -1213,15 +1214,17 @@ void AddStarGiftTable( && (unique->starsForTransfer >= 0); auto send = transfer ? tr::lng_gift_unique_owner_change() : nullptr; auto handler = transfer ? Fn([=] { - ShowTransferGiftBox( - controller->parentController(), - entry.uniqueGift, - MsgId(entry.bareMsgId)); + if (const auto window = show->resolveWindow()) { + ShowTransferGiftBox( + window, + entry.uniqueGift, + MsgId(entry.bareMsgId)); + } }) : nullptr; AddTableRow( table, tr::lng_gift_unique_owner(), - MakePeerTableValue(table, controller, ownerId, send, handler), + MakePeerTableValue(table, show, ownerId, send, handler), st::giveawayGiftCodePeerMargin); } else if (unique) { AddTableRow( @@ -1234,19 +1237,21 @@ void AddStarGiftTable( const auto withSendButton = entry.in && user && !user->isBot(); auto send = withSendButton ? tr::lng_gift_send_small() : nullptr; auto handler = send ? Fn([=] { - Ui::ShowStarGiftBox(controller->parentController(), user); + if (const auto window = show->resolveWindow()) { + Ui::ShowStarGiftBox(window, user); + } }) : nullptr; AddTableRow( table, tr::lng_credits_box_history_entry_peer_in(), - MakePeerTableValue(table, controller, peerId, send, handler), + MakePeerTableValue(table, show, peerId, send, handler), st::giveawayGiftCodePeerMargin); } } else if (!entry.soldOutInfo) { AddTableRow( table, tr::lng_credits_box_history_entry_peer_in(), - MakeHiddenPeerTableValue(table, controller), + MakeHiddenPeerTableValue(table), st::giveawayGiftCodePeerMargin); } if (!unique && !entry.firstSaleDate.isNull()) { @@ -1357,7 +1362,7 @@ void AddStarGiftTable( tr::lng_gift_link_label_value(), MakeStarGiftStarsValue( table, - controller, + show, entry, std::move(convertToStars)), marginWithButton); @@ -1368,7 +1373,6 @@ void AddStarGiftTable( tr::lng_gift_visibility(), MakeVisibilityTableValue( table, - controller, entry.savedToProfile, std::move(toggleVisibility)), marginWithButton); @@ -1398,16 +1402,13 @@ void AddStarGiftTable( AddTableRow( table, tr::lng_gift_unique_status(), - MakeNonUniqueStatusTableValue( - table, - controller, - std::move(startUpgrade)), + MakeNonUniqueStatusTableValue(table, std::move(startUpgrade)), marginWithButton); } if (unique) { const auto &original = unique->originalDetails; if (original.recipientId) { - const auto owner = &controller->session().data(); + const auto owner = &show->session().data(); const auto to = owner->peer(original.recipientId); const auto from = original.senderId ? owner->peer(original.senderId).get() @@ -1462,8 +1463,7 @@ void AddStarGiftTable( makeContext); const auto showBoxLink = [=](not_null peer) { return std::make_shared([=] { - controller->uiShow()->showBox( - PrepareShortInfoBox(peer, controller)); + show->showBox(PrepareShortInfoBox(peer, show)); }); }; label->setLink(1, showBoxLink(to)); @@ -1500,7 +1500,7 @@ void AddStarGiftTable( } void AddCreditsHistoryEntryTable( - not_null controller, + std::shared_ptr show, not_null container, const Data::CreditsHistoryEntry &entry) { if (!entry) { @@ -1514,7 +1514,7 @@ void AddCreditsHistoryEntryTable( const auto peerId = PeerId(entry.barePeerId); const auto actorId = PeerId(entry.bareActorId); const auto starrefRecipientId = PeerId(entry.starrefRecipientId); - const auto session = &controller->session(); + const auto session = &show->session(); if (entry.starrefCommission) { if (entry.starrefAmount) { AddTableRow( @@ -1534,7 +1534,7 @@ void AddCreditsHistoryEntryTable( AddTableRow( table, tr::lng_credits_box_history_entry_affiliate(), - controller, + show, starrefRecipientId); } if (peerId && entry.starrefCommission) { @@ -1543,7 +1543,7 @@ void AddCreditsHistoryEntryTable( (entry.starrefAmount ? tr::lng_credits_box_history_entry_referred : tr::lng_credits_box_history_entry_miniapp)(), - controller, + show, peerId); } if (actorId || (!entry.starrefCommission && peerId)) { @@ -1557,7 +1557,7 @@ void AddCreditsHistoryEntryTable( AddTableRow( table, std::move(text), - controller, + show, actorId ? actorId : peerId); } if (const auto msgId = MsgId(peerId ? entry.bareMsgId : 0)) { @@ -1572,7 +1572,9 @@ void AddCreditsHistoryEntryTable( rpl::single(Ui::Text::Link(link)), st::giveawayGiftCodeValue); label->setClickHandlerFilter([=](const auto &...) { - controller->showPeerHistory(channel, {}, msgId); + if (const auto window = show->resolveWindow()) { + window->showPeerHistory(channel, {}, msgId); + } return false; }); AddTableRow( @@ -1623,8 +1625,8 @@ void AddCreditsHistoryEntryTable( AddTableRow( table, tr::lng_gift_link_label_to(), - controller, - controller->session().userId()); + show, + show->session().userId()); } if (entry.bareGiveawayMsgId && entry.credits) { AddTableRow( @@ -1670,7 +1672,7 @@ void AddCreditsHistoryEntryTable( label->setClickHandlerFilter([=](const auto &...) { TextUtilities::SetClipboardText( TextForMimeData::Simple(entry.id)); - controller->showToast( + show->showToast( tr::lng_credits_box_history_entry_id_copied(tr::now)); return false; }); @@ -1710,7 +1712,7 @@ void AddCreditsHistoryEntryTable( } void AddSubscriptionEntryTable( - not_null controller, + std::shared_ptr show, not_null container, const Data::SubscriptionEntry &s) { if (!s) { @@ -1723,7 +1725,7 @@ void AddSubscriptionEntryTable( st::giveawayGiftCodeTableMargin); const auto peerId = PeerId(s.barePeerId); const auto user = peerIsUser(peerId) - ? controller->session().data().peer(peerId)->asUser() + ? show->session().data().peer(peerId)->asUser() : nullptr; AddTableRow( table, @@ -1732,7 +1734,7 @@ void AddSubscriptionEntryTable( : (!s.title.isEmpty() && user && !user->botInfo) ? tr::lng_credits_subscription_row_to_business() : tr::lng_credits_subscription_row_to(), - controller, + show, peerId); if (!s.title.isEmpty()) { AddTableRow( @@ -1763,7 +1765,7 @@ void AddSubscriptionEntryTable( } void AddSubscriberEntryTable( - not_null controller, + std::shared_ptr show, not_null container, not_null peer, TimeId date) { @@ -1775,7 +1777,7 @@ void AddSubscriberEntryTable( AddTableRow( table, tr::lng_group_invite_joined_row_subscriber(), - controller, + show, peer->id); if (const auto d = base::unixtime::parse(date); !d.isNull()) { AddTableRow( @@ -1786,7 +1788,7 @@ void AddSubscriberEntryTable( } void AddCreditsBoostTable( - not_null controller, + std::shared_ptr show, not_null container, const Data::Boost &b) { auto table = container->add( @@ -1798,11 +1800,11 @@ void AddCreditsBoostTable( if (!peerId) { return; } - const auto from = controller->session().data().peer(peerId); + const auto from = show->session().data().peer(peerId); AddTableRow( table, tr::lng_credits_box_history_entry_peer_in(), - controller, + show, from->id); if (b.credits) { AddTableRow( @@ -1815,7 +1817,7 @@ void AddCreditsBoostTable( } { const auto link = CreateMessageLink( - &controller->session(), + &show->session(), peerId, b.giveawayMessage.msg.bare); if (!link.isEmpty()) { diff --git a/Telegram/SourceFiles/boxes/gift_premium_box.h b/Telegram/SourceFiles/boxes/gift_premium_box.h index d29c1fca4..8aea2e6f9 100644 --- a/Telegram/SourceFiles/boxes/gift_premium_box.h +++ b/Telegram/SourceFiles/boxes/gift_premium_box.h @@ -13,6 +13,10 @@ namespace Api { struct GiftCode; } // namespace Api +namespace ChatHelpers { +class Show; +} // namespace ChatHelpers + namespace Data { struct Boost; struct CreditsHistoryEntry; @@ -55,28 +59,28 @@ void ResolveGiveawayInfo( std::optional results); void AddStarGiftTable( - not_null controller, + std::shared_ptr show, not_null container, const Data::CreditsHistoryEntry &entry, Fn toggleVisibility, Fn convertToStars, Fn startUpgrade); void AddCreditsHistoryEntryTable( - not_null controller, + std::shared_ptr show, not_null container, const Data::CreditsHistoryEntry &entry); void AddSubscriptionEntryTable( - not_null controller, + std::shared_ptr show, not_null container, const Data::SubscriptionEntry &s); void AddSubscriberEntryTable( - not_null controller, + std::shared_ptr show, not_null container, not_null peer, TimeId date); void AddCreditsBoostTable( - not_null controller, + std::shared_ptr show, not_null container, const Data::Boost &boost); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp index d1d666411..589e0613a 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp @@ -872,8 +872,7 @@ int ColorSelector::resizeGetHeight(int newWidth) { const auto customTextColor = [=] { return style->coloredValues(false, state->index).name; }; - const auto controller = show->resolveWindow( - ChatHelpers::WindowUsage::PremiumPromo); + const auto controller = show->resolveWindow(); if (controller) { state->panel.show({ .controller = controller, @@ -986,8 +985,7 @@ int ColorSelector::resizeGetHeight(int newWidth) { }, right->lifetime()); raw->setClickedCallback([=] { - const auto controller = show->resolveWindow( - ChatHelpers::WindowUsage::PremiumPromo); + const auto controller = show->resolveWindow(); if (controller) { state->panel.show({ .controller = controller, @@ -1264,8 +1262,7 @@ void EditPeerColorBox( { &st::menuBlueIconWallpaper } ); button->setClickedCallback([=] { - const auto usage = ChatHelpers::WindowUsage::PremiumPromo; - if (const auto strong = show->resolveWindow(usage)) { + if (const auto strong = show->resolveWindow()) { show->show(Box(strong, channel)); } }); @@ -1472,8 +1469,7 @@ void CheckBoostLevel( return; } const auto openStatistics = [=] { - if (const auto controller = show->resolveWindow( - ChatHelpers::WindowUsage::PremiumPromo)) { + if (const auto controller = show->resolveWindow()) { controller->showSection(Info::Boosts::Make(peer)); } }; diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp index 29504ab63..e771275a8 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp @@ -1019,7 +1019,8 @@ void Controller::rowClicked(not_null row) { Ui::AddSkip(content); Ui::AddSkip(content); - AddSubscriberEntryTable(controller, content, row->peer(), data.date); + const auto show = controller->uiShow(); + AddSubscriberEntryTable(show, content, row->peer(), data.date); Ui::AddSkip(content); Ui::AddSkip(content); diff --git a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp index 760a821c7..9341b7089 100644 --- a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp @@ -486,20 +486,23 @@ object_ptr PrepareShortInfoBox( object_ptr PrepareShortInfoBox( not_null peer, - not_null navigation, + std::shared_ptr show, const style::ShortInfoBox *stOverride) { - const auto open = [=] { navigation->showPeerHistory(peer); }; + const auto open = [=] { + if (const auto window = show->resolveWindow()) { + window->showPeerHistory(peer); + } + }; const auto videoIsPaused = [=] { - return navigation->parentController()->isGifPausedAtLeastFor( - Window::GifPauseReason::Layer); + return show->paused(Window::GifPauseReason::Layer); }; auto menuFiller = [=](Ui::Menu::MenuCallback addAction) { - const auto controller = navigation->parentController(); const auto peerSeparateId = Window::SeparateId(peer); - if (controller->windowId() != peerSeparateId) { + const auto window = show->resolveWindow(); + if (window && window->windowId() != peerSeparateId) { addAction(tr::lng_context_new_window(tr::now), [=] { Ui::PreventDelayedActivation(); - controller->showInNewWindow(peer); + window->showInNewWindow(peer); }, &st::menuIconNewWindow); } }; @@ -511,6 +514,13 @@ object_ptr PrepareShortInfoBox( stOverride); } +object_ptr PrepareShortInfoBox( + not_null peer, + not_null navigation, + const style::ShortInfoBox *stOverride) { + return PrepareShortInfoBox(peer, navigation->uiShow(), stOverride); +} + rpl::producer PrepareShortInfoStatus(not_null peer) { return StatusValue(peer); } diff --git a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h index 2edd5cd92..2213f4da2 100644 --- a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h +++ b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h @@ -16,6 +16,10 @@ struct ShortInfoCover; struct ShortInfoBox; } // namespace style +namespace ChatHelpers { +class Show; +} // namespace ChatHelpers + namespace Ui::Menu { struct MenuCallback; } // namespace Ui::Menu @@ -42,6 +46,11 @@ struct PreparedShortInfoUserpic { Fn menuFiller, const style::ShortInfoBox *stOverride = nullptr); +[[nodiscard]] object_ptr PrepareShortInfoBox( + not_null peer, + std::shared_ptr show, + const style::ShortInfoBox *stOverride = nullptr); + [[nodiscard]] object_ptr PrepareShortInfoBox( not_null peer, not_null navigation, diff --git a/Telegram/SourceFiles/boxes/premium_preview_box.cpp b/Telegram/SourceFiles/boxes/premium_preview_box.cpp index 2ef807604..570fb75e6 100644 --- a/Telegram/SourceFiles/boxes/premium_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/premium_preview_box.cpp @@ -1139,8 +1139,7 @@ void PreviewBox( button->resizeToWidth(width); if (!descriptor.fromSettings) { button->setClickedCallback([=] { - const auto window = show->resolveWindow( - ChatHelpers::WindowUsage::PremiumPromo); + const auto window = show->resolveWindow(); if (!window) { return; } diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index 14902a9ee..8ddbb7720 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -773,9 +773,7 @@ void StickerSetBox::updateButtons() { - st.buttonPadding.left() - st.buttonPadding.left()); button->setClickedCallback([=] { - using namespace ChatHelpers; - const auto usage = WindowUsage::PremiumPromo; - if (const auto window = _show->resolveWindow(usage)) { + if (const auto window = _show->resolveWindow()) { Settings::ShowPremium(window, u"animated_emoji"_q); } }); diff --git a/Telegram/SourceFiles/chat_helpers/compose/compose_show.cpp b/Telegram/SourceFiles/chat_helpers/compose/compose_show.cpp index ba904b77c..192937b6e 100644 --- a/Telegram/SourceFiles/chat_helpers/compose/compose_show.cpp +++ b/Telegram/SourceFiles/chat_helpers/compose/compose_show.cpp @@ -19,7 +19,7 @@ rpl::producer Show::adjustShadowLeft() const { } ResolveWindow ResolveWindowDefault() { - return [](not_null session, WindowUsage usage) + return [](not_null session) -> Window::SessionController* { const auto check = [&](Window::Controller *window) { if (const auto controller = window->sessionController()) { @@ -45,8 +45,8 @@ ResolveWindow ResolveWindowDefault() { }; } -Window::SessionController *Show::resolveWindow(WindowUsage usage) const { - return ResolveWindowDefault()(&session(), usage); +Window::SessionController *Show::resolveWindow() const { + return ResolveWindowDefault()(&session()); } } // namespace ChatHelpers diff --git a/Telegram/SourceFiles/chat_helpers/compose/compose_show.h b/Telegram/SourceFiles/chat_helpers/compose/compose_show.h index 28fc7ff47..95ed8046e 100644 --- a/Telegram/SourceFiles/chat_helpers/compose/compose_show.h +++ b/Telegram/SourceFiles/chat_helpers/compose/compose_show.h @@ -40,13 +40,8 @@ enum class PauseReason { using PauseReasons = base::flags; inline constexpr bool is_flag_type(PauseReason) { return true; }; -enum class WindowUsage { - PremiumPromo, -}; - using ResolveWindow = Fn, - WindowUsage)>; + not_null)>; [[nodiscard]] ResolveWindow ResolveWindowDefault(); class Show : public Main::SessionShow { @@ -68,8 +63,7 @@ public: virtual void processChosenSticker(FileChosen &&chosen) const = 0; - [[nodiscard]] virtual Window::SessionController *resolveWindow( - WindowUsage) const; + [[nodiscard]] virtual Window::SessionController *resolveWindow() const; }; } // namespace ChatHelpers diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp index 7ea95f736..1e35337b8 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp @@ -1751,7 +1751,6 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) { const auto id = hasColorButton(button->section) ? 0 : _custom[button->section - _staticCount].id; - const auto usage = ChatHelpers::WindowUsage::PremiumPromo; if (hasColorButton(button->section)) { _pickerSelected = pressed; showPicker(); @@ -1759,7 +1758,7 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) { removeSet(id); } else if (hasAddButton(button->section)) { _localSetsManager->install(id); - } else if (const auto resolved = _show->resolveWindow(usage)) { + } else if (const auto resolved = _show->resolveWindow()) { _jumpedToPremium.fire({}); switch (_mode) { case Mode::Full: diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index 8eb165894..fed2bbd12 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -237,8 +237,7 @@ StickersListWidget::StickersListWidget( } _settings->addClickHandler([=] { - if (const auto window = _show->resolveWindow( - WindowUsage::PremiumPromo)) { + if (const auto window = _show->resolveWindow()) { // While media viewer can't show StickersBox. using Section = StickersBox::Section; window->show( diff --git a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp index 8148b31f8..4c7efa83a 100644 --- a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp +++ b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp @@ -1061,8 +1061,7 @@ void TabbedSelector::checkRestrictedPeer() { st::stickersRestrictedLabel); const auto lifting = error.boostsToLift; _restrictedLabel->setClickHandlerFilter([=](auto...) { - const auto window = show->resolveWindow( - ChatHelpers::WindowUsage::PremiumPromo); + const auto window = show->resolveWindow(); window->resolveBoostState(peer->asChannel(), lifting); return false; }); diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index bdeb03614..7a07c26dd 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -1355,45 +1355,7 @@ bool ResolveUniqueGift( if (slug.isEmpty()) { return false; } - struct Request { - base::weak_ptr weak; - QString slug; - mtpRequestId id = 0; - }; - static auto request = Request(); - if (request.weak.get() == controller && request.slug == slug) { - return true; - } else if (const auto strong = request.weak.get()) { - strong->session().api().request(request.id).cancel(); - } - const auto weak = request.weak = controller; - request.slug = slug; - const auto clear = [slug](not_null window) { - if (request.weak.get() == window && request.slug == slug) { - request = {}; - } - }; - request.id = controller->session().api().request( - MTPpayments_GetUniqueStarGift(MTP_string(slug)) - ).done([=](const MTPpayments_UniqueStarGift &result) { - if (const auto strong = weak.get()) { - clear(strong); - - const auto &data = result.data(); - const auto session = &strong->session(); - session->data().processUsers(data.vusers()); - if (const auto gift = Api::FromTL(session, data.vgift())) { - using namespace ::Settings; - strong->show(Box(GlobalStarGiftBox, strong, *gift)); - } - } - }).fail([=](const MTP::Error &error) { - if (const auto strong = weak.get()) { - clear(strong); - - strong->showToast(u"Error: "_q + error.type()); - } - }).send(); + ResolveAndShowUniqueGift(controller->uiShow(), slug); return true; } @@ -1738,4 +1700,44 @@ bool StartUrlRequiresActivate(const QString &url) { : !InternalPassportLink(url); } +void ResolveAndShowUniqueGift( + std::shared_ptr show, + const QString &slug) { + struct Request { + base::weak_ptr weak; + QString slug; + mtpRequestId id = 0; + }; + static auto request = Request(); + + const auto session = &show->session(); + if (request.weak.get() == session && request.slug == slug) { + return; + } else if (const auto strong = request.weak.get()) { + strong->api().request(request.id).cancel(); + } + request.weak = session; + request.slug = slug; + const auto clear = [=] { + if (request.weak.get() == session && request.slug == slug) { + request = {}; + } + }; + request.id = session->api().request( + MTPpayments_GetUniqueStarGift(MTP_string(slug)) + ).done([=](const MTPpayments_UniqueStarGift &result) { + clear(); + + const auto &data = result.data(); + session->data().processUsers(data.vusers()); + if (const auto gift = Api::FromTL(session, data.vgift())) { + using namespace ::Settings; + show->show(Box(GlobalStarGiftBox, show, *gift)); + } + }).fail([=](const MTP::Error &error) { + clear(); + show->showToast(u"Error: "_q + error.type()); + }).send(); +} + } // namespace Core diff --git a/Telegram/SourceFiles/core/local_url_handlers.h b/Telegram/SourceFiles/core/local_url_handlers.h index 9a5cc6a55..50af3c2d1 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.h +++ b/Telegram/SourceFiles/core/local_url_handlers.h @@ -11,6 +11,10 @@ namespace qthelp { class RegularExpressionMatch; } // namespace qthelp +namespace ChatHelpers { +class Show; +} // namespace ChatHelpers + namespace Window { class SessionController; } // namespace Window @@ -34,4 +38,8 @@ struct LocalUrlHandler { [[nodiscard]] bool StartUrlRequiresActivate(const QString &url); +void ResolveAndShowUniqueGift( + std::shared_ptr show, + const QString &slug); + } // namespace Core diff --git a/Telegram/SourceFiles/data/data_chat_participant_status.cpp b/Telegram/SourceFiles/data/data_chat_participant_status.cpp index c184bff5c..537663a36 100644 --- a/Telegram/SourceFiles/data/data_chat_participant_status.cpp +++ b/Telegram/SourceFiles/data/data_chat_participant_status.cpp @@ -416,8 +416,7 @@ void ShowSendErrorToast( return; } const auto boost = [=] { - const auto window = show->resolveWindow( - ChatHelpers::WindowUsage::PremiumPromo); + const auto window = show->resolveWindow(); window->resolveBoostState(peer->asChannel(), error.boostsToLift); }; show->showToast({ diff --git a/Telegram/SourceFiles/data/data_story.cpp b/Telegram/SourceFiles/data/data_story.cpp index 8aec4e166..d5a5fc57e 100644 --- a/Telegram/SourceFiles/data/data_story.cpp +++ b/Telegram/SourceFiles/data/data_story.cpp @@ -158,6 +158,10 @@ using UpdateFlag = StoryUpdate::Flag; }); }, [&](const MTPDmediaAreaWeather &data) { }, [&](const MTPDmediaAreaStarGift &data) { + result.emplace(UrlArea{ + .area = ParseArea(data.vcoordinates()), + .url = u"tg://nft?slug="_q + qs(data.vslug()), + }); }, [&](const MTPDinputMediaAreaChannelPost &data) { LOG(("API Error: Unexpected inputMediaAreaChannelPost from API.")); }, [&](const MTPDinputMediaAreaVenue &data) { diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.cpp b/Telegram/SourceFiles/data/stickers/data_stickers.cpp index d04b880a6..114d41176 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.cpp +++ b/Telegram/SourceFiles/data/stickers/data_stickers.cpp @@ -88,8 +88,7 @@ void MaybeShowPremiumToast( return; } const auto filter = [=](const auto ...) { - const auto usage = ChatHelpers::WindowUsage::PremiumPromo; - if (const auto controller = show->resolveWindow(usage)) { + if (const auto controller = show->resolveWindow()) { Settings::ShowPremium(controller, ref); } return false; diff --git a/Telegram/SourceFiles/history/history_item_helpers.cpp b/Telegram/SourceFiles/history/history_item_helpers.cpp index 1c6584e85..d2f557c7f 100644 --- a/Telegram/SourceFiles/history/history_item_helpers.cpp +++ b/Telegram/SourceFiles/history/history_item_helpers.cpp @@ -178,8 +178,7 @@ object_ptr MakeSendErrorBox( Expects(peer->isChannel()); const auto window = ChatHelpers::ResolveWindowDefault()( - &peer->session(), - ChatHelpers::WindowUsage::PremiumPromo); + &peer->session()); window->resolveBoostState(peer->asChannel(), lifting); return false; }; diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index f801347e2..1f88adeec 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -2317,8 +2317,7 @@ void SetupRestrictionView( tr::lng_restricted_boost_group(tr::now), st::historyComposeButton); state->button->setClickedCallback([=] { - const auto window = show->resolveWindow( - ChatHelpers::WindowUsage::PremiumPromo); + const auto window = show->resolveWindow(); window->resolveBoostState(peer->asChannel(), lifting); }); } else if (value.type == Type::Rights) { diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index ebb96889a..66a7b980c 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -479,8 +479,7 @@ bool CheckEmojiStatusPremium(not_null bot) { return true; } const auto window = ChatHelpers::ResolveWindowDefault()( - &bot->session(), - ChatHelpers::WindowUsage::PremiumPromo); + &bot->session()); if (window) { ShowPremiumPreviewBox(window, PremiumFeature::EmojiStatus); window->window().activate(); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 06bea1d04..1af7432da 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1347,6 +1347,7 @@ void MainWidget::showHistory( } if (peerId && params.activation != anim::activation::background) { + Core::App().hideMediaView(); _controller->window().activate(); } diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp index c0ca0eb43..444a2d15c 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/application.h" #include "core/click_handler_types.h" #include "core/core_settings.h" +#include "core/local_url_handlers.h" #include "core/update_checker.h" #include "data/data_changes.h" #include "data/data_document.h" @@ -1274,11 +1275,12 @@ ClickHandlerPtr Controller::lookupAreaHandler(QPoint point) const { }); } } + const auto weak = base::make_weak(this); for (const auto &url : _urlAreas) { _areas.push_back({ .original = url.area.geometry, .rotation = url.area.rotation, - .handler = std::make_shared(url.url), + .handler = MakeUrlAreaHandler(weak, url.url), }); } for (const auto &weather : _weatherAreas) { @@ -1940,4 +1942,34 @@ ClickHandlerPtr MakeChannelPostHandler( })); } +ClickHandlerPtr MakeUrlAreaHandler( + base::weak_ptr weak, + const QString &url) { + class Handler final : public HiddenUrlClickHandler { + public: + Handler(const QString &url, base::weak_ptr weak) + : HiddenUrlClickHandler(url), _weak(weak) { + } + + void onClick(ClickContext context) const override { + const auto raw = url(); + const auto strong = _weak.get(); + const auto prefix = u"tg://nft?slug="_q; + if (raw.startsWith(prefix) && strong) { + const auto slug = raw.mid( + prefix.size() + ).split('&').front().split('#').front(); + Core::ResolveAndShowUniqueGift(strong->uiShow(), slug); + } else { + HiddenUrlClickHandler::onClick(context); + } + } + + private: + base::weak_ptr _weak; + + }; + return std::make_shared(url, weak); +} + } // namespace Media::Stories diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.h b/Telegram/SourceFiles/media/stories/media_stories_controller.h index 860908b96..5daba8d59 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.h +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.h @@ -349,5 +349,8 @@ void ReportRequested( [[nodiscard]] ClickHandlerPtr MakeChannelPostHandler( not_null session, FullMsgId item); +[[nodiscard]] ClickHandlerPtr MakeUrlAreaHandler( + base::weak_ptr weak, + const QString &url); } // namespace Media::Stories diff --git a/Telegram/SourceFiles/media/stories/media_stories_stealth.cpp b/Telegram/SourceFiles/media/stories/media_stories_stealth.cpp index 3578e3fb0..b64de9eaf 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_stealth.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_stealth.cpp @@ -350,8 +350,7 @@ struct Feature { box->closeBox(); } else if (!now.premium) { data->requested = false; - const auto usage = ChatHelpers::WindowUsage::PremiumPromo; - if (const auto window = show->resolveWindow(usage)) { + if (const auto window = show->resolveWindow()) { ShowPremiumPreviewBox(window, PremiumFeature::Stories); window->window().activate(); } diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 57f4f295b..0df0d0777 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -1332,8 +1332,7 @@ void OverlayWidget::checkForSaveLoaded() { void OverlayWidget::showPremiumDownloadPromo() { const auto filter = [=](const auto &...) { - const auto usage = ChatHelpers::WindowUsage::PremiumPromo; - if (const auto window = uiShow()->resolveWindow(usage)) { + if (const auto window = uiShow()->resolveWindow()) { ShowPremiumPreviewBox(window, PremiumFeature::Stories); window->window().activate(); } diff --git a/Telegram/SourceFiles/menu/menu_send.cpp b/Telegram/SourceFiles/menu/menu_send.cpp index dd8807784..118bcee59 100644 --- a/Telegram/SourceFiles/menu/menu_send.cpp +++ b/Telegram/SourceFiles/menu/menu_send.cpp @@ -522,8 +522,7 @@ void EffectPreview::setupSend(Details details) { }, _actionWithEffect); } else { _premiumPromoLabel->entity()->setClickHandlerFilter([=](auto&&...) { - const auto window = _show->resolveWindow( - ChatHelpers::WindowUsage::PremiumPromo); + const auto window = _show->resolveWindow(); if (window) { if (const auto onstack = _close) { onstack(); diff --git a/Telegram/SourceFiles/settings/business/settings_chat_intro.cpp b/Telegram/SourceFiles/settings/business/settings_chat_intro.cpp index 688a6940d..a15e49259 100644 --- a/Telegram/SourceFiles/settings/business/settings_chat_intro.cpp +++ b/Telegram/SourceFiles/settings/business/settings_chat_intro.cpp @@ -303,9 +303,7 @@ rpl::producer> IconPlayerValue( }, right->lifetime()); raw->setClickedCallback([=] { - const auto controller = show->resolveWindow( - ChatHelpers::WindowUsage::PremiumPromo); - if (controller) { + if (const auto controller = show->resolveWindow()) { state->panel.show({ .controller = controller, .button = right, diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index b6a3acfd3..9e51f202b 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -170,29 +170,24 @@ private: }; void ToggleStarGiftSaved( - not_null window, + std::shared_ptr show, not_null sender, MsgId itemId, bool save, Fn done) { using Flag = MTPpayments_SaveStarGift::Flag; - const auto api = &window->session().api(); - const auto weak = base::make_weak(window); + const auto api = &show->session().api(); api->request(MTPpayments_SaveStarGift( MTP_flags(save ? Flag(0) : Flag::f_unsave), MTP_int(itemId.bare) )).done([=] { done(true); - if (const auto strong = weak.get()) { - strong->showToast((save - ? tr::lng_gift_display_done - : tr::lng_gift_display_done_hide)(tr::now)); - } + show->showToast((save + ? tr::lng_gift_display_done + : tr::lng_gift_display_done_hide)(tr::now)); }).fail([=](const MTP::Error &error) { done(false); - if (const auto strong = weak.get()) { - strong->showToast(error.type()); - } + show->showToast(error.type()); }).send(); } @@ -229,36 +224,33 @@ void ConfirmConvertStarGift( } void ConvertStarGift( - not_null window, + std::shared_ptr show, not_null sender, MsgId itemId, int stars, Fn done) { - const auto api = &window->session().api(); - const auto weak = base::make_weak(window); + const auto api = &show->session().api(); api->request(MTPpayments_ConvertStarGift( MTP_int(itemId) )).done([=] { - if (const auto strong = weak.get()) { - strong->showSettings(Settings::CreditsId()); - strong->showToast(tr::lng_gift_got_stars( - tr::now, - lt_count, - stars, - Ui::Text::RichLangValue)); + if (const auto window = show->resolveWindow()) { + window->showSettings(Settings::CreditsId()); } + show->showToast(tr::lng_gift_got_stars( + tr::now, + lt_count, + stars, + Ui::Text::RichLangValue)); done(true); }).fail([=](const MTP::Error &error) { - if (const auto strong = weak.get()) { - strong->showToast(error.type()); - } + show->showToast(error.type()); done(false); }).send(); } void AddViewMediaHandler( not_null thumb, - not_null controller, + std::shared_ptr show, const Data::CreditsHistoryEntry &e) { if (e.extended.empty()) { return; @@ -277,7 +269,7 @@ void AddViewMediaHandler( bool over = false; }; const auto state = thumb->lifetime().make_state(); - const auto session = &controller->session(); + const auto session = &show->session(); const auto owner = &session->data(); const auto peerId = e.barePeerId ? PeerId(e.barePeerId) @@ -315,24 +307,27 @@ void AddViewMediaHandler( .extendedMedia = std::move(fake), .isPaidMedia = true, })); - const auto showMedia = crl::guard(controller, [=] { - if (const auto media = state->item->media()) { + const auto showMedia = [=] { + const auto window = show->resolveWindow(); + if (!window) { + return; + } else if (const auto media = state->item->media()) { if (const auto invoice = media->invoice()) { if (!invoice->extendedMedia.empty()) { const auto first = invoice->extendedMedia[0].get(); if (const auto photo = first->photo()) { - controller->openPhoto(photo, { + window->openPhoto(photo, { .id = state->item->fullId(), }); } else if (const auto document = first->document()) { - controller->openDocument(document, true, { + window->openDocument(document, true, { .id = state->item->fullId(), }); } } } } - }); + }; thumb->events() | rpl::start_with_next([=](not_null e) { if (e->type() == QEvent::MouseButtonPress) { const auto mouse = static_cast(e.get()); @@ -780,7 +775,7 @@ void BoostCreditsBox( Ui::AddSkip(content); } - AddCreditsBoostTable(controller, content, b); + AddCreditsBoostTable(controller->uiShow(), content, b); Ui::AddSkip(content); box->addRow(object_ptr>( @@ -831,28 +826,21 @@ void ProcessReceivedSubscriptions( } void FillUniqueGiftMenu( - not_null controller, + std::shared_ptr show, not_null menu, const Data::CreditsHistoryEntry &e) { Expects(e.uniqueGift != nullptr); const auto unique = e.uniqueGift; - const auto show = controller->uiShow(); - const auto weak = base::make_weak(controller); const auto local = u"nft/"_q + unique->slug; - const auto url = controller->session().createInternalLinkFull(local); + const auto url = show->session().createInternalLinkFull(local); menu->addAction(tr::lng_context_copy_link(tr::now), [=] { TextUtilities::SetClipboardText({ url }); - if (const auto strong = weak.get()) { - strong->showToast( - tr::lng_channel_public_link_copied(tr::now)); - } + show->showToast(tr::lng_channel_public_link_copied(tr::now)); }, &st::menuIconLink); menu->addAction(tr::lng_chat_link_share(tr::now), [=] { - if (const auto strong = weak.get()) { - FastShareLink(strong, url); - } + FastShareLink(show, url); }, &st::menuIconShare); const auto messageId = MsgId(e.bareMsgId); @@ -861,20 +849,23 @@ void FillUniqueGiftMenu( && (unique->starsForTransfer >= 0); if (transfer) { menu->addAction(tr::lng_gift_transfer_button(tr::now), [=] { - if (const auto strong = weak.get()) { - ShowTransferGiftBox(strong, unique, messageId); + if (const auto window = show->resolveWindow()) { + ShowTransferGiftBox(window, unique, messageId); } }, &st::menuIconReplace); } } -void ReceiptCreditsBox( +void GenericCreditsEntryBox( not_null box, - not_null controller, + std::shared_ptr show, const Data::CreditsHistoryEntry &e, const Data::SubscriptionEntry &s) { - const auto item = controller->session().data().message( - PeerId(e.barePeerId), MsgId(e.bareMsgId)); + const auto session = &show->session(); + const auto owner = &session->data(); + const auto item = owner->message( + PeerId(e.barePeerId), + MsgId(e.bareMsgId)); const auto isStarGift = e.stargift || e.soldOutInfo; const auto creditsHistoryStarGift = isStarGift && !e.id.isEmpty(); const auto sentStarGift = creditsHistoryStarGift && !e.in; @@ -883,10 +874,10 @@ void ReceiptCreditsBox( const auto starGiftSender = (isStarGift && item) ? item->history()->peer->asUser() : (isStarGift && e.in) - ? controller->session().data().peer(PeerId(e.barePeerId))->asUser() + ? owner->peer(PeerId(e.barePeerId))->asUser() : nullptr; const auto convertLast = base::unixtime::serialize(e.date) - + controller->session().appConfig().stargiftConvertPeriodMax(); + + session->appConfig().stargiftConvertPeriodMax(); const auto timeLeft = int64(convertLast) - int64(base::unixtime::now()); const auto timeExceeded = (timeLeft <= 0); const auto uniqueGift = e.uniqueGift.get(); @@ -912,21 +903,20 @@ void ReceiptCreditsBox( using Type = Data::CreditsHistoryEntry::PeerType; const auto &stUser = st::boostReplaceUserpic; - const auto session = &controller->session(); const auto isPrize = e.bareGiveawayMsgId > 0; const auto starGiftSticker = (isStarGift && e.bareGiftStickerId) - ? session->data().document(e.bareGiftStickerId).get() + ? owner->document(e.bareGiftStickerId).get() : nullptr; const auto peer = isPrize ? nullptr : (s.barePeerId) - ? session->data().peer(PeerId(s.barePeerId)).get() + ? owner->peer(PeerId(s.barePeerId)).get() : (e.peerType == Type::PremiumBot) ? nullptr : e.bareActorId - ? session->data().peer(PeerId(e.bareActorId)).get() + ? owner->peer(PeerId(e.bareActorId)).get() : e.barePeerId - ? session->data().peer(PeerId(e.barePeerId)).get() + ? owner->peer(PeerId(e.barePeerId)).get() : nullptr; if (uniqueGift) { box->setNoContentMargin(true); @@ -936,13 +926,13 @@ void ReceiptCreditsBox( AddSkip(content, st::defaultVerticalListSkip * 2); AddUniqueCloseButton(box, [=](not_null menu) { - FillUniqueGiftMenu(controller, menu, e); + FillUniqueGiftMenu(show, menu, e); }); } else if (const auto callback = Ui::PaintPreviewCallback(session, e)) { const auto thumb = content->add(object_ptr>( content, GenericEntryPhoto(content, callback, stUser.photoSize))); - AddViewMediaHandler(thumb->entity(), controller, e); + AddViewMediaHandler(thumb->entity(), show, e); } else if (s.photoId || (e.photoId && !e.subscriptionUntil.isNull())) { if (!(s.cancelled || s.expired || s.cancelledByBot)) { const auto widget = Ui::CreateChild(content); @@ -952,7 +942,7 @@ void ReceiptCreditsBox( const auto photoId = s.photoId ? s.photoId : e.photoId; const auto callback = [=](Fn update) { return Ui::GenerateCreditsPaintEntryCallback( - session->data().photo(photoId), + owner->photo(photoId), std::move(update)); }; content->add(object_ptr>( @@ -1132,7 +1122,7 @@ void ReceiptCreditsBox( tr::lng_credits_subscription_subtitle( tr::now, lt_emoji, - session->data().customEmojiManager().creditsEmoji(), + owner->customEmojiManager().creditsEmoji(), lt_cost, { QString::number(s.subscription.credits) }, Ui::Text::WithEntities), @@ -1147,7 +1137,7 @@ void ReceiptCreditsBox( : QString(kMinus)) .append(Lang::FormatStarsAmountDecimal(e.credits.abs())) .append(QChar(' ')) - .append(session->data().customEmojiManager().creditsEmoji()); + .append(owner->customEmojiManager().creditsEmoji()); text->setMarkedText( st::semiboldTextStyle, std::move(t), @@ -1280,7 +1270,7 @@ void ReceiptCreditsBox( } else if (e.gift || isPrize) { Ui::AddSkip(content); const auto arrow = Ui::Text::SingleCustomEmoji( - session->data().customEmojiManager().registerInternalEmoji( + owner->customEmojiManager().registerInternalEmoji( st::topicButtonArrow, st::channelEarnLearnArrowMargins, true)); @@ -1320,28 +1310,23 @@ void ReceiptCreditsBox( rpl::variable convertButtonBusy; }; const auto state = box->lifetime().make_state(); - const auto weakWindow = base::make_weak(controller); const auto toggleVisibility = [=, weak = Ui::MakeWeak(box)](bool save) { - const auto window = weakWindow.get(); const auto showSection = !e.fromGiftsList; const auto itemId = MsgId(e.bareMsgId); - if (!window) { - return; - } const auto done = [=](bool ok) { - if (const auto window = weakWindow.get()) { - if (ok) { - using GiftAction = Data::GiftUpdate::Action; - window->session().data().notifyGiftUpdate({ - .itemId = FullMsgId( - starGiftSender->id, - itemId), - .action = (save - ? GiftAction::Save - : GiftAction::Unsave), - }); - if (showSection) { + if (ok) { + using GiftAction = Data::GiftUpdate::Action; + show->session().data().notifyGiftUpdate({ + .itemId = FullMsgId( + starGiftSender->id, + itemId), + .action = (save + ? GiftAction::Save + : GiftAction::Unsave), + }); + if (showSection) { + if (const auto window = show->resolveWindow()) { window->showSection( std::make_shared( window->session().user(), @@ -1357,39 +1342,33 @@ void ReceiptCreditsBox( } } }; - ToggleStarGiftSaved( - window, - starGiftSender, - itemId, - save, - done); + ToggleStarGiftSaved(show, starGiftSender, itemId, save, done); }; const auto upgradeGuard = std::make_shared(); const auto upgrade = [=] { - if (const auto window = weakWindow.get()) { - const auto itemId = MsgId(e.bareMsgId); - if (*upgradeGuard) { - return; - } - *upgradeGuard = true; - using namespace Ui; - ShowStarGiftUpgradeBox({ - .controller = window, - .stargiftId = e.stargiftId, - .ready = [=](bool) { *upgradeGuard = false; }, - .user = starGiftSender, - .itemId = itemId, - .cost = e.starsUpgradedBySender ? 0 : e.starsToUpgrade, - .canAddSender = !giftToSelf && !e.anonymous, - .canAddComment = (!giftToSelf - && !e.anonymous - && e.hasGiftComment), - .canAddMyComment = (giftToSelf && e.hasGiftComment), - .addDetailsDefault = (giftToSelf - || (e.starsUpgradedBySender && !e.anonymous)), - }); + const auto itemId = MsgId(e.bareMsgId); + const auto window = show->resolveWindow(); + if (!window || *upgradeGuard) { + return; } + *upgradeGuard = true; + using namespace Ui; + ShowStarGiftUpgradeBox({ + .controller = window, + .stargiftId = e.stargiftId, + .ready = [=](bool) { *upgradeGuard = false; }, + .user = starGiftSender, + .itemId = itemId, + .cost = e.starsUpgradedBySender ? 0 : e.starsToUpgrade, + .canAddSender = !giftToSelf && !e.anonymous, + .canAddComment = (!giftToSelf + && !e.anonymous + && e.hasGiftComment), + .canAddMyComment = (giftToSelf && e.hasGiftComment), + .addDetailsDefault = (giftToSelf + || (e.starsUpgradedBySender && !e.anonymous)), + }); }; const auto canUpgrade = e.stargiftId && e.canUpgradeGift @@ -1402,26 +1381,23 @@ void ReceiptCreditsBox( const auto stars = e.starsConverted; const auto days = canConvert ? ((timeLeft + 86399) / 86400) : 0; const auto name = starGiftSender->shortName(); - ConfirmConvertStarGift(box->uiShow(), name, stars, days, [=] { + ConfirmConvertStarGift(show, name, stars, days, [=] { if (state->convertButtonBusy.current() || state->confirmButtonBusy.current()) { return; } state->convertButtonBusy = true; - const auto window = weakWindow.get(); const auto itemId = MsgId(e.bareMsgId); - if (window && stars) { + if (stars) { const auto done = [=](bool ok) { - if (const auto window = weakWindow.get()) { - if (ok) { - using GiftAction = Data::GiftUpdate::Action; - window->session().data().notifyGiftUpdate({ - .itemId = FullMsgId( - starGiftSender->id, - itemId), - .action = GiftAction::Convert, - }); - } + if (ok) { + using GiftAction = Data::GiftUpdate::Action; + show->session().data().notifyGiftUpdate({ + .itemId = FullMsgId( + starGiftSender->id, + itemId), + .action = GiftAction::Convert, + }); } if (const auto strong = weak.data()) { if (ok) { @@ -1432,7 +1408,7 @@ void ReceiptCreditsBox( } }; ConvertStarGift( - window, + show, starGiftSender, itemId, stars, @@ -1445,15 +1421,15 @@ void ReceiptCreditsBox( && !e.giftRefunded; AddStarGiftTable( - controller, + show, content, e, canToggle ? toggleVisibility : Fn(), canConvert ? convert : Fn(), canUpgrade ? upgrade : Fn()); } else { - AddCreditsHistoryEntryTable(controller, content, e); - AddSubscriptionEntryTable(controller, content, s); + AddCreditsHistoryEntryTable(show, content, e); + AddSubscriptionEntryTable(show, content, s); } Ui::AddSkip(content); @@ -1565,7 +1541,7 @@ void ReceiptCreditsBox( : tr::lng_box_ok())); const auto send = [=, weak = Ui::MakeWeak(box)] { if (toRejoin) { - if (const auto window = weakWindow.get()) { + if (const auto window = show->resolveWindow()) { const auto finish = [=](Payments::CheckoutResult&&) { ProcessReceivedSubscriptions(weak, session); }; @@ -1578,9 +1554,11 @@ void ReceiptCreditsBox( finish)); } } else if (toRenew && s.expired) { - Api::CheckChatInvite(controller, s.inviteHash, nullptr, [=] { - ProcessReceivedSubscriptions(weak, session); - }); + if (const auto window = show->resolveWindow()) { + Api::CheckChatInvite(window, s.inviteHash, nullptr, [=] { + ProcessReceivedSubscriptions(weak, session); + }); + } } else { const auto done = [=] { ProcessReceivedSubscriptions(weak, session); @@ -1638,6 +1616,14 @@ void ReceiptCreditsBox( }, button->lifetime()); } +void ReceiptCreditsBox( + not_null box, + not_null controller, + const Data::CreditsHistoryEntry &e, + const Data::SubscriptionEntry &s) { + GenericCreditsEntryBox(box, controller->uiShow(), e, s); +} + void GiftedCreditsBox( not_null box, not_null controller, @@ -1691,12 +1677,12 @@ void CreditsPrizeBox( void GlobalStarGiftBox( not_null box, - not_null controller, + std::shared_ptr show, const Data::StarGift &data) { const auto ownerId = data.unique ? data.unique->ownerId.value : 0; - Settings::ReceiptCreditsBox( + Settings::GenericCreditsEntryBox( box, - controller, + show, Data::CreditsHistoryEntry{ .credits = StarsAmount(data.stars), .bareGiftStickerId = data.document->id, @@ -1708,7 +1694,7 @@ void GlobalStarGiftBox( .limitedLeft = data.limitedLeft, .stargift = true, .fromGiftSlug = true, - .in = (ownerId == controller->session().userPeerId().value), + .in = (ownerId == show->session().userPeerId().value), .gift = true, }, Data::SubscriptionEntry()); diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.h b/Telegram/SourceFiles/settings/settings_credits_graphics.h index 6893fa2e0..b9db70447 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.h +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.h @@ -12,6 +12,10 @@ class object_ptr; class PeerData; +namespace ChatHelpers { +class Show; +} // namespace ChatHelpers + namespace Data { struct Boost; struct CreditsHistoryEntry; @@ -77,6 +81,11 @@ void AddWithdrawalWidget( bool withdrawalEnabled, rpl::producer usdValue); +void GenericCreditsEntryBox( + not_null box, + std::shared_ptr show, + const Data::CreditsHistoryEntry &e, + const Data::SubscriptionEntry &s); void ReceiptCreditsBox( not_null box, not_null controller, @@ -100,7 +109,7 @@ void CreditsPrizeBox( TimeId date); void GlobalStarGiftBox( not_null box, - not_null controller, + std::shared_ptr show, const Data::StarGift &data); void UserStarGiftBox( not_null box, diff --git a/Telegram/SourceFiles/settings/settings_premium.cpp b/Telegram/SourceFiles/settings/settings_premium.cpp index 172420fd8..89bfff492 100644 --- a/Telegram/SourceFiles/settings/settings_premium.cpp +++ b/Telegram/SourceFiles/settings/settings_premium.cpp @@ -1376,19 +1376,17 @@ void ShowPremiumPromoToast( TextWithEntities textWithLink, const QString &ref) { ShowPremiumPromoToast(show, [=]( - not_null session, - ChatHelpers::WindowUsage usage) { + not_null session) { Expects(&show->session() == session); - return show->resolveWindow(usage); + return show->resolveWindow(); }, std::move(textWithLink), ref); } void ShowPremiumPromoToast( std::shared_ptr show, Fn, - ChatHelpers::WindowUsage)> resolveWindow, + not_null)> resolveWindow, TextWithEntities textWithLink, const QString &ref) { using WeakToast = base::weak_ptr; @@ -1403,8 +1401,7 @@ void ShowPremiumPromoToast( strong->hideAnimated(); (*toast) = nullptr; if (const auto controller = resolveWindow( - &show->session(), - ChatHelpers::WindowUsage::PremiumPromo)) { + &show->session())) { Settings::ShowPremium(controller, ref); } return true; @@ -1476,12 +1473,10 @@ not_null CreateSubscribeButton( Expects(args.show || args.controller); auto show = args.show ? std::move(args.show) : args.controller->uiShow(); - auto resolve = [show]( - not_null session, - ChatHelpers::WindowUsage usage) { + auto resolve = [show](not_null session) { Expects(session == &show->session()); - return show->resolveWindow(usage); + return show->resolveWindow(); }; return CreateSubscribeButton( std::move(show), @@ -1492,8 +1487,7 @@ not_null CreateSubscribeButton( not_null CreateSubscribeButton( std::shared_ptr<::Main::SessionShow> show, Fn, - ChatHelpers::WindowUsage)> resolveWindow, + not_null<::Main::Session*>)> resolveWindow, SubscribeButtonArgs &&args) { const auto result = Ui::CreateChild( args.parent.get(), @@ -1508,8 +1502,7 @@ not_null CreateSubscribeButton( computeRef = args.computeRef, computeBotUrl = args.computeBotUrl] { const auto window = resolveWindow( - &show->session(), - ChatHelpers::WindowUsage::PremiumPromo); + &show->session()); if (!window) { return; } else if (promo) { diff --git a/Telegram/SourceFiles/settings/settings_premium.h b/Telegram/SourceFiles/settings/settings_premium.h index 3a6ef6896..2effb1e1a 100644 --- a/Telegram/SourceFiles/settings/settings_premium.h +++ b/Telegram/SourceFiles/settings/settings_premium.h @@ -18,7 +18,6 @@ struct RoundButton; namespace ChatHelpers { class Show; -enum class WindowUsage; } // namespace ChatHelpers namespace Ui { @@ -66,9 +65,7 @@ void ShowPremiumPromoToast( const QString &ref); void ShowPremiumPromoToast( std::shared_ptr<::Main::SessionShow> show, - Fn, - ChatHelpers::WindowUsage)> resolveWindow, + Fn)> resolveWindow, TextWithEntities textWithLink, const QString &ref); @@ -95,9 +92,7 @@ struct SubscribeButtonArgs final { [[nodiscard]] not_null CreateSubscribeButton( std::shared_ptr<::Main::SessionShow> show, - Fn, - ChatHelpers::WindowUsage)> resolveWindow, + Fn)> resolveWindow, SubscribeButtonArgs &&args); [[nodiscard]] std::vector PremiumFeaturesOrder(