Handle today-birthday click in profile.

This commit is contained in:
John Preston 2024-03-29 18:59:24 +04:00
parent 20123fca7f
commit d788f5afac
7 changed files with 150 additions and 14 deletions

View file

@ -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 }};

View file

@ -1014,6 +1014,30 @@ void GiftPremiumValidator::showChoosePeerBox(const QString &ref) {
}, _manyGiftsLifetime);
}
void GiftPremiumValidator::showChosenPeerBox(
not_null<UserData*> user,
const QString &ref) {
if (_manyGiftsLifetime) {
return;
}
using namespace Api;
const auto api = _manyGiftsLifetime.make_state<PremiumGiftCodeOptions>(
_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<not_null<UserData*>>{ 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<UserData*> user) {
if (_requestId) {
return;

View file

@ -35,6 +35,7 @@ public:
void showBox(not_null<UserData*> user);
void showChoosePeerBox(const QString &ref);
void showChosenPeerBox(not_null<UserData*> user, const QString &ref);
void cancel();
private:

View file

@ -598,6 +598,104 @@ base::options::toggle ShowPeerIdBelowAbout({
return result;
}
[[nodiscard]] object_ptr<Ui::SlideWrap<>> CreateBirthday(
not_null<QWidget*> parent,
not_null<Window::SessionController*> controller,
not_null<UserData*> user) {
using namespace Data;
auto result = object_ptr<Ui::SlideWrap<Ui::RoundButton>>(
parent,
object_ptr<Ui::RoundButton>(
parent,
rpl::single(QString()),
st::infoHoursOuter),
st::infoProfileLabeledPadding - st::infoHoursOuterMargin);
result->setDuration(st::infoSlideDuration);
const auto button = result->entity();
auto outer = Ui::CreateChild<Ui::SlideWrap<Ui::VerticalLayout>>(
button,
object_ptr<Ui::VerticalLayout>(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<Ui::RpWidget>(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<Ui::FlatLabel>(
layout,
std::move(nonEmptyText),
st::birthdayLabeled));
layout->add(Ui::CreateSkipWidget(layout, st::infoLabelSkip));
const auto subtext = layout->add(object_ptr<Ui::FlatLabel>(
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 <typename Text, typename ToggleOn, typename Callback>
auto AddActionButton(
not_null<Ui::VerticalLayout*> parent,
@ -1004,14 +1102,8 @@ object_ptr<Ui::RpWidget> 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(

View file

@ -668,12 +668,14 @@ rpl::producer<QString> 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(

View file

@ -1346,6 +1346,12 @@ void SessionController::showGiftPremiumsBox(const QString &ref) {
_giftPremiumValidator.showChoosePeerBox(ref);
}
void SessionController::showGiftPremiumsBox(
not_null<UserData*> user,
const QString &ref) {
_giftPremiumValidator.showChosenPeerBox(user, ref);
}
void SessionController::init() {
if (session().supportMode()) {
session().supportHelper().registerWindow(this);

View file

@ -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<UserData*> user, const QString &ref);
void enableGifPauseReason(GifPauseReason reason);
void disableGifPauseReason(GifPauseReason reason);
rpl::producer<> gifPauseLevelChanged() const {