diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 02dd7a92fd..0f859e7465 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3863,10 +3863,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_dialogs_skip_archive_in_search" = "Skip results from archive"; "lng_dialogs_show_archive_in_search" = "With results from archive"; -"lng_dialogs_top_bar_suggestions_birthday_title" = "Add your birthday! 🎂"; -"lng_dialogs_top_bar_suggestions_birthday_about" = "Let your contacts know when you’re celebrating."; -"lng_dialogs_top_bar_suggestions_premium_annual_title" = "Telegram Premium with a {text} discount"; -"lng_dialogs_top_bar_suggestions_premium_annual_about" = "Sign up for the annual payment plan for Telegram Premium now to get the discount."; +"lng_dialogs_suggestions_birthday_title" = "Add your birthday! 🎂"; +"lng_dialogs_suggestions_birthday_about" = "Let your contacts know when you’re celebrating."; +"lng_dialogs_suggestions_premium_annual_title" = "Telegram Premium with a {text} discount"; +"lng_dialogs_suggestions_premium_annual_about" = "Sign up for the annual payment plan for Telegram Premium now to get the discount."; "lng_about_random" = "Send a {emoji} emoji to any chat to try your luck."; "lng_about_random_send" = "Send"; diff --git a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp index 9589cba5a7..f810364acd 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp @@ -39,119 +39,140 @@ constexpr auto kSugPremiumAnnual = "PREMIUM_ANNUAL"_cs; } // namespace -object_ptr> CreateTopBarSuggestion( +rpl::producer*> TopBarSuggestionValue( not_null parent, not_null session) { - const auto content = Ui::CreateChild(parent); - auto result = object_ptr>( - parent, - object_ptr::fromRaw(content)); - const auto wrap = result.data(); - wrap->toggle(false, anim::type::instant); - struct State { - rpl::lifetime birthdayLifetime; - rpl::lifetime premiumLifetime; - }; - const auto state = content->lifetime().make_state(); + return [=](auto consumer) { + auto lifetime = rpl::lifetime(); - const auto processCurrentSuggestion = [=](auto repeat) -> void { - if (session->appConfig().suggestionCurrent(kSugSetBirthday.utf8()) - && !Data::IsBirthdayToday(session->user()->birthday())) { - content->setRightIcon(TopBarSuggestionContent::RightIcon::Close); - content->setClickedCallback([=] { - const auto controller = FindSessionController(parent); - if (!controller) { - return; - } - Core::App().openInternalUrl( - u"internal:edit_birthday"_q, - QVariant::fromValue(ClickHandlerContext{ - .sessionWindow = base::make_weak(controller), - })); + struct State { + TopBarSuggestionContent *content = nullptr; + Ui::SlideWrap *wrap = nullptr; + rpl::lifetime birthdayLifetime; + rpl::lifetime premiumLifetime; + }; + const auto state = lifetime.make_state(); + const auto ensureWrap = [=] { + if (!state->content) { + state->content = Ui::CreateChild( + parent); + rpl::combine( + parent->widthValue(), + state->content->desiredHeightValue() + ) | rpl::start_with_next([=](int width, int height) { + state->content->resize(width, height); + }, state->content->lifetime()); + } + if (!state->wrap) { + state->wrap = Ui::CreateChild>( + parent, + object_ptr::fromRaw(state->content)); + state->wrap->toggle(false, anim::type::instant); + } + }; - state->birthdayLifetime = Info::Profile::BirthdayValue( - session->user() - ) | rpl::map( - Data::IsBirthdayTodayValue - ) | rpl::flatten_latest( - ) | rpl::distinct_until_changed( - ) | rpl::start_with_next([=] { - repeat(repeat); - }); - }); - content->setHideCallback([=] { - session->appConfig().dismissSuggestion( - kSugSetBirthday.utf8()); - repeat(repeat); - }); - content->setContent( - tr::lng_dialogs_top_bar_suggestions_birthday_title( - tr::now, - Ui::Text::Bold), - tr::lng_dialogs_top_bar_suggestions_birthday_about( - tr::now, - TextWithEntities::Simple)); - wrap->toggle(true, anim::type::normal); - } else if (session->premiumPossible() - && !session->premium() - && session->appConfig().suggestionCurrent( - kSugPremiumAnnual.utf8())) { - content->setRightIcon(TopBarSuggestionContent::RightIcon::Arrow); - const auto api = &session->api().premium(); - const auto set = [=](QString discount) { - constexpr auto kMinus = QChar(0x2212); - content->setContent( - tr::lng_dialogs_top_bar_suggestions_premium_annual_title( - tr::now, - lt_text, - { discount.replace(kMinus, QChar()) }, - Ui::Text::Bold), - tr::lng_dialogs_top_bar_suggestions_premium_annual_about( - tr::now, - TextWithEntities::Simple)); + const auto processCurrentSuggestion = [=](auto repeat) -> void { + ensureWrap(); + const auto content = state->content; + const auto wrap = state->wrap; + using RightIcon = TopBarSuggestionContent::RightIcon; + if (session->appConfig().suggestionCurrent(kSugSetBirthday.utf8()) + && !Data::IsBirthdayToday(session->user()->birthday())) { + content->setRightIcon(RightIcon::Close); content->setClickedCallback([=] { const auto controller = FindSessionController(parent); if (!controller) { return; } - Settings::ShowPremium(controller, "dialogs_hint"); + Core::App().openInternalUrl( + u"internal:edit_birthday"_q, + QVariant::fromValue(ClickHandlerContext{ + .sessionWindow = base::make_weak(controller), + })); + + state->birthdayLifetime = Info::Profile::BirthdayValue( + session->user() + ) | rpl::map( + Data::IsBirthdayTodayValue + ) | rpl::flatten_latest( + ) | rpl::distinct_until_changed( + ) | rpl::start_with_next([=] { + repeat(repeat); + }); + }); + content->setHideCallback([=] { session->appConfig().dismissSuggestion( - kSugPremiumAnnual.utf8()); + kSugSetBirthday.utf8()); repeat(repeat); }); + content->setContent( + tr::lng_dialogs_suggestions_birthday_title( + tr::now, + Ui::Text::Bold), + tr::lng_dialogs_suggestions_birthday_about( + tr::now, + TextWithEntities::Simple)); wrap->toggle(true, anim::type::normal); - }; - api->statusTextValue( - ) | rpl::start_with_next([=] { - for (const auto &option : api->subscriptionOptions()) { - if (option.months == 12) { - set(option.discount); - state->premiumLifetime.destroy(); - return; + } else if (session->premiumPossible() + && !session->premium() + && session->appConfig().suggestionCurrent( + kSugPremiumAnnual.utf8())) { + content->setRightIcon(RightIcon::Arrow); + const auto api = &session->api().premium(); + const auto set = [=](QString discount) { + constexpr auto kMinus = QChar(0x2212); + content->setContent( + tr::lng_dialogs_suggestions_premium_annual_title( + tr::now, + lt_text, + { discount.replace(kMinus, QChar()) }, + Ui::Text::Bold), + tr::lng_dialogs_suggestions_premium_annual_about( + tr::now, + TextWithEntities::Simple)); + content->setClickedCallback([=] { + const auto controller = FindSessionController(parent); + if (!controller) { + return; + } + Settings::ShowPremium(controller, "dialogs_hint"); + session->appConfig().dismissSuggestion( + kSugPremiumAnnual.utf8()); + repeat(repeat); + }); + wrap->toggle(true, anim::type::normal); + }; + api->statusTextValue( + ) | rpl::start_with_next([=] { + for (const auto &option : api->subscriptionOptions()) { + if (option.months == 12) { + set(option.discount); + state->premiumLifetime.destroy(); + return; + } } - } - }, state->premiumLifetime); - api->reload(); - } else { - wrap->toggle(false, anim::type::normal); - base::call_delayed(st::slideWrapDuration * 2, wrap, [=] { - delete wrap; - }); - } + }, state->premiumLifetime); + api->reload(); + } else { + wrap->toggle(false, anim::type::normal); + base::call_delayed(st::slideWrapDuration * 2, wrap, [=] { + state->content = nullptr; + state->wrap = nullptr; + consumer.put_next(nullptr); + }); + } + }; + + session->appConfig().value() | rpl::start_with_next([=] { + const auto was = state->wrap; + processCurrentSuggestion(processCurrentSuggestion); + if (was != state->wrap) { + consumer.put_next_copy(state->wrap); + } + }, lifetime); + + return lifetime; }; - - session->appConfig().refreshed() | rpl::start_with_next([=] { - processCurrentSuggestion(processCurrentSuggestion); - }, content->lifetime()); - - rpl::combine( - parent->widthValue(), - content->desiredHeightValue() - ) | rpl::start_with_next([=](int width, int height) { - content->resize(width, height); - }, content->lifetime()); - - return result; } } // namespace Dialogs diff --git a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.h b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.h index 631ea2dcad..4ff01525c6 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.h +++ b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.h @@ -22,9 +22,10 @@ class SlideWrap; namespace Dialogs { -[[nodiscard]] object_ptr> CreateTopBarSuggestion( +[[nodiscard]] auto TopBarSuggestionValue( not_null parent, - not_null); + not_null) +-> rpl::producer*>; } // namespace Dialogs diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index ef1913176c..dd3934622a 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -380,23 +380,34 @@ Widget::Widget( const auto innerList = _scroll->setOwnedWidget( object_ptr(this)); if (_layout != Layout::Child) { - _topBarSuggestion = innerList->add(CreateTopBarSuggestion( + TopBarSuggestionValue( innerList, - &session())); - _topBarSuggestion->lifetime().add([=] { - _topBarSuggestion = nullptr; - }); - rpl::combine( - _topBarSuggestion->entity()->desiredHeightValue(), - _childListShown.value() - ) | rpl::start_with_next([=](int desiredHeight, float64 shown) { - const auto newHeight = desiredHeight * (1. - shown); - _topBarSuggestion->entity()->setMaximumHeight(newHeight); - _topBarSuggestion->entity()->setMinimumWidth((shown > 0) - ? width() - : 0); - _topBarSuggestion->entity()->resize(width(), newHeight); - }, _topBarSuggestion->lifetime()); + &session() + ) | rpl::start_with_next([=](Ui::SlideWrap *raw) { + if (raw) { + _topBarSuggestion = innerList->insert( + 0, + object_ptr>::fromRaw(raw)); + rpl::combine( + _topBarSuggestion->entity()->desiredHeightValue(), + _childListShown.value() + ) | rpl::start_with_next([=]( + int desiredHeight, + float64 shown) { + const auto newHeight = desiredHeight * (1. - shown); + _topBarSuggestion->entity()->setMaximumHeight(newHeight); + _topBarSuggestion->entity()->setMinimumWidth((shown > 0) + ? width() + : 0); + _topBarSuggestion->entity()->resize(width(), newHeight); + }, _topBarSuggestion->lifetime()); + } else { + if (_topBarSuggestion) { + delete _topBarSuggestion; + } + _topBarSuggestion = nullptr; + } + }, lifetime()); } _inner = innerList->add(object_ptr( innerList,