From d788f5afac5e106c9290d1e65d391ab6f811b6db Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 29 Mar 2024 18:59:24 +0400 Subject: [PATCH] Handle today-birthday click in profile. --- Telegram/SourceFiles/boxes/boxes.style | 8 ++ .../SourceFiles/boxes/gift_premium_box.cpp | 24 ++++ Telegram/SourceFiles/boxes/gift_premium_box.h | 1 + .../info/profile/info_profile_actions.cpp | 108 ++++++++++++++++-- .../info/profile/info_profile_values.cpp | 14 ++- .../window/window_session_controller.cpp | 6 + .../window/window_session_controller.h | 3 + 7 files changed, 150 insertions(+), 14 deletions(-) diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 14a859e76..c7a23f366 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -1020,3 +1020,11 @@ shortInfoBox: ShortInfoBox { labeled: infoLabeled; labeledOneLine: infoLabeledOneLine; } + +birthdayLabeled: FlatLabel(infoLabeled) { + margin: margins(0px, 0px, 0px, 0px); +} +birthdayLabel: FlatLabel(infoLabel) { + margin: margins(0px, 0px, 0px, 0px); +} +birthdayTodayIcon: icon {{ "menu/gift_premium", windowActiveTextFg }}; diff --git a/Telegram/SourceFiles/boxes/gift_premium_box.cpp b/Telegram/SourceFiles/boxes/gift_premium_box.cpp index 41f9cc097..19907b080 100644 --- a/Telegram/SourceFiles/boxes/gift_premium_box.cpp +++ b/Telegram/SourceFiles/boxes/gift_premium_box.cpp @@ -1014,6 +1014,30 @@ void GiftPremiumValidator::showChoosePeerBox(const QString &ref) { }, _manyGiftsLifetime); } +void GiftPremiumValidator::showChosenPeerBox( + not_null user, + const QString &ref) { + if (_manyGiftsLifetime) { + return; + } + using namespace Api; + const auto api = _manyGiftsLifetime.make_state( + _controller->session().user()); + const auto show = _controller->uiShow(); + api->request( + ) | rpl::start_with_error_done([=](const QString &error) { + show->showToast(error); + }, [=] { + const auto users = std::vector>{ user }; + const auto giftBox = show->show( + Box(GiftsBox, _controller, users, api, ref)); + giftBox->boxClosing( + ) | rpl::start_with_next([=] { + _manyGiftsLifetime.destroy(); + }, giftBox->lifetime()); + }, _manyGiftsLifetime); +} + void GiftPremiumValidator::showBox(not_null user) { if (_requestId) { return; diff --git a/Telegram/SourceFiles/boxes/gift_premium_box.h b/Telegram/SourceFiles/boxes/gift_premium_box.h index ed001200e..b054bc3a2 100644 --- a/Telegram/SourceFiles/boxes/gift_premium_box.h +++ b/Telegram/SourceFiles/boxes/gift_premium_box.h @@ -35,6 +35,7 @@ public: void showBox(not_null user); void showChoosePeerBox(const QString &ref); + void showChosenPeerBox(not_null user, const QString &ref); void cancel(); private: diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp index 1f5e23a1a..37863f5a5 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp @@ -598,6 +598,104 @@ base::options::toggle ShowPeerIdBelowAbout({ return result; } +[[nodiscard]] object_ptr> CreateBirthday( + not_null parent, + not_null controller, + not_null user) { + using namespace Data; + + auto result = object_ptr>( + parent, + object_ptr( + parent, + rpl::single(QString()), + st::infoHoursOuter), + st::infoProfileLabeledPadding - st::infoHoursOuterMargin); + result->setDuration(st::infoSlideDuration); + const auto button = result->entity(); + + auto outer = Ui::CreateChild>( + button, + object_ptr(button), + st::infoHoursOuterMargin); + const auto layout = outer->entity(); + layout->setAttribute(Qt::WA_TransparentForMouseEvents); + + auto birthday = BirthdayValue( + user + ) | rpl::start_spawning(result->lifetime()); + + auto label = BirthdayLabelText(rpl::duplicate(birthday)); + auto text = BirthdayValueText( + rpl::duplicate(birthday) + ) | Ui::Text::ToWithEntities(); + + const auto giftIcon = Ui::CreateChild(layout); + giftIcon->resize(st::birthdayTodayIcon.size()); + layout->sizeValue() | rpl::start_with_next([=](QSize size) { + giftIcon->moveToRight( + 0, + (size.height() - giftIcon->height()) / 2, + size.width()); + }, giftIcon->lifetime()); + giftIcon->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(giftIcon); + st::birthdayTodayIcon.paint(p, 0, 0, giftIcon->width()); + }, giftIcon->lifetime()); + + rpl::duplicate( + birthday + ) | rpl::map([](Data::Birthday value) { + return Data::IsBirthdayTodayValue(value); + }) | rpl::flatten_latest( + ) | rpl::distinct_until_changed( + ) | rpl::start_with_next([=](bool today) { + const auto disable = !today && user->session().premiumCanBuy(); + button->setDisabled(disable); + button->setAttribute(Qt::WA_TransparentForMouseEvents, disable); + button->clearState(); + giftIcon->setVisible(!disable); + }, result->lifetime()); + + auto nonEmptyText = std::move( + text + ) | rpl::before_next([slide = result.data()]( + const TextWithEntities &value) { + if (value.text.isEmpty()) { + slide->hide(anim::type::normal); + } + }) | rpl::filter([](const TextWithEntities &value) { + return !value.text.isEmpty(); + }) | rpl::after_next([slide = result.data()]( + const TextWithEntities &value) { + slide->show(anim::type::normal); + }); + auto labeled = layout->add(object_ptr( + layout, + std::move(nonEmptyText), + st::birthdayLabeled)); + layout->add(Ui::CreateSkipWidget(layout, st::infoLabelSkip)); + const auto subtext = layout->add(object_ptr( + layout, + std::move( + label + ) | rpl::after_next([=] { + layout->resizeToWidth(layout->widthNoMargins()); + }), + st::birthdayLabel)); + result->finishAnimating(); + + Ui::ResizeFitChild(button, outer); + + button->setClickedCallback([=] { + if (!button->isDisabled()) { + controller->showGiftPremiumsBox(user, u"birthday"_q); + } + }); + + return result; +} + template auto AddActionButton( not_null parent, @@ -1004,14 +1102,8 @@ object_ptr DetailsFiller::setupInfo() { return false; }); } else { - addInfoOneLine( - BirthdayLabelText(BirthdayValue(user)), - BirthdayValueText( - BirthdayValue(user) - ) | Ui::Text::ToWithEntities(), - tr::lng_mediaview_copy(tr::now), - st::infoProfileLabeledUsernamePadding); - + tracker.track(result->add( + CreateBirthday(result, controller, user))); tracker.track(result->add(CreateWorkingHours(result, user))); auto locationText = user->session().changes().peerFlagsValue( diff --git a/Telegram/SourceFiles/info/profile/info_profile_values.cpp b/Telegram/SourceFiles/info/profile/info_profile_values.cpp index aa10dff08..9fe23da1f 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_values.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_values.cpp @@ -668,12 +668,14 @@ rpl::producer BirthdayValueText( ) | rpl::map([=](bool today) { auto text = Data::BirthdayText(value); if (const auto age = Data::BirthdayAge(value)) { - text = tr::lng_info_birthday_years( - tr::now, - lt_count, - age, - lt_date, - text); + text = (today + ? tr::lng_info_birthday_today_years + : tr::lng_info_birthday_years)( + tr::now, + lt_count, + age, + lt_date, + text); } if (today) { text = tr::lng_info_birthday_today( diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 183c0c110..18c536cf3 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -1346,6 +1346,12 @@ void SessionController::showGiftPremiumsBox(const QString &ref) { _giftPremiumValidator.showChoosePeerBox(ref); } +void SessionController::showGiftPremiumsBox( + not_null user, + const QString &ref) { + _giftPremiumValidator.showChosenPeerBox(user, ref); +} + void SessionController::init() { if (session().supportMode()) { session().supportHelper().registerWindow(this); diff --git a/Telegram/SourceFiles/window/window_session_controller.h b/Telegram/SourceFiles/window/window_session_controller.h index 063a2485a..811fb87a3 100644 --- a/Telegram/SourceFiles/window/window_session_controller.h +++ b/Telegram/SourceFiles/window/window_session_controller.h @@ -395,6 +395,9 @@ public: void showGiftPremiumBox(UserData *user); void showGiftPremiumsBox(const QString &ref); + // Single user gift as if was selected in multiple recipients chooser. + void showGiftPremiumsBox(not_null user, const QString &ref); + void enableGifPauseReason(GifPauseReason reason); void disableGifPauseReason(GifPauseReason reason); rpl::producer<> gifPauseLevelChanged() const {