mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Display date of birth in user profiles.
This commit is contained in:
parent
c82d7bd909
commit
08ee25deb2
10 changed files with 166 additions and 22 deletions
|
@ -1329,6 +1329,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_info_mobile_hidden" = "Hidden";
|
"lng_info_mobile_hidden" = "Hidden";
|
||||||
"lng_info_username_label" = "Username";
|
"lng_info_username_label" = "Username";
|
||||||
"lng_info_usernames_label" = "also";
|
"lng_info_usernames_label" = "also";
|
||||||
|
"lng_info_birthday_label" = "Date of birth";
|
||||||
|
"lng_info_birthday_years#one" = "{date} ({count} year old)";
|
||||||
|
"lng_info_birthday_years#other" = "{date} ({count} years old)";
|
||||||
|
"lng_info_birthday_today_label" = "Birthday today";
|
||||||
|
"lng_info_birthday_today" = "{emoji} {date}";
|
||||||
"lng_info_bio_label" = "Bio";
|
"lng_info_bio_label" = "Bio";
|
||||||
"lng_info_link_label" = "Link";
|
"lng_info_link_label" = "Link";
|
||||||
"lng_info_location_label" = "Location";
|
"lng_info_location_label" = "Location";
|
||||||
|
|
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
#include "info/profile/info_profile_text.h"
|
#include "info/profile/info_profile_text.h"
|
||||||
|
#include "info/profile/info_profile_values.h"
|
||||||
#include "media/streaming/media_streaming_instance.h"
|
#include "media/streaming/media_streaming_instance.h"
|
||||||
#include "media/streaming/media_streaming_player.h"
|
#include "media/streaming/media_streaming_player.h"
|
||||||
#include "base/event_filter.h"
|
#include "base/event_filter.h"
|
||||||
|
@ -788,6 +789,10 @@ void PeerShortInfoBox::prepareRows() {
|
||||||
tr::lng_info_username_label(),
|
tr::lng_info_username_label(),
|
||||||
usernameValue() | Ui::Text::ToWithEntities(),
|
usernameValue() | Ui::Text::ToWithEntities(),
|
||||||
tr::lng_context_copy_mention(tr::now));
|
tr::lng_context_copy_mention(tr::now));
|
||||||
|
addInfoOneLine(
|
||||||
|
birthdayLabel(),
|
||||||
|
birthdayValue() | Ui::Text::ToWithEntities(),
|
||||||
|
tr::lng_mediaview_copy(tr::now));
|
||||||
}
|
}
|
||||||
|
|
||||||
RectParts PeerShortInfoBox::customCornersFilling() {
|
RectParts PeerShortInfoBox::customCornersFilling() {
|
||||||
|
@ -827,29 +832,47 @@ void PeerShortInfoBox::refreshRoundedTopImage(const QColor &color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<QString> PeerShortInfoBox::nameValue() const {
|
rpl::producer<QString> PeerShortInfoBox::nameValue() const {
|
||||||
return _fields.value() | rpl::map([](const PeerShortInfoFields &fields) {
|
return _fields.value(
|
||||||
|
) | rpl::map([](const PeerShortInfoFields &fields) {
|
||||||
return fields.name;
|
return fields.name;
|
||||||
}) | rpl::distinct_until_changed();
|
}) | rpl::distinct_until_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<TextWithEntities> PeerShortInfoBox::linkValue() const {
|
rpl::producer<TextWithEntities> PeerShortInfoBox::linkValue() const {
|
||||||
return _fields.value() | rpl::map([](const PeerShortInfoFields &fields) {
|
return _fields.value(
|
||||||
|
) | rpl::map([](const PeerShortInfoFields &fields) {
|
||||||
return Ui::Text::Link(fields.link, fields.link);
|
return Ui::Text::Link(fields.link, fields.link);
|
||||||
}) | rpl::distinct_until_changed();
|
}) | rpl::distinct_until_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<QString> PeerShortInfoBox::phoneValue() const {
|
rpl::producer<QString> PeerShortInfoBox::phoneValue() const {
|
||||||
return _fields.value() | rpl::map([](const PeerShortInfoFields &fields) {
|
return _fields.value(
|
||||||
|
) | rpl::map([](const PeerShortInfoFields &fields) {
|
||||||
return fields.phone;
|
return fields.phone;
|
||||||
}) | rpl::distinct_until_changed();
|
}) | rpl::distinct_until_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<QString> PeerShortInfoBox::usernameValue() const {
|
rpl::producer<QString> PeerShortInfoBox::usernameValue() const {
|
||||||
return _fields.value() | rpl::map([](const PeerShortInfoFields &fields) {
|
return _fields.value(
|
||||||
|
) | rpl::map([](const PeerShortInfoFields &fields) {
|
||||||
return fields.username;
|
return fields.username;
|
||||||
}) | rpl::distinct_until_changed();
|
}) | rpl::distinct_until_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<QString> PeerShortInfoBox::birthdayLabel() const {
|
||||||
|
return Info::Profile::BirthdayLabelText(_fields.value(
|
||||||
|
) | rpl::map([](const PeerShortInfoFields &fields) {
|
||||||
|
return fields.birthday;
|
||||||
|
}) | rpl::distinct_until_changed());
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<QString> PeerShortInfoBox::birthdayValue() const {
|
||||||
|
return Info::Profile::BirthdayValueText(_fields.value(
|
||||||
|
) | rpl::map([](const PeerShortInfoFields &fields) {
|
||||||
|
return fields.birthday;
|
||||||
|
}) | rpl::distinct_until_changed());
|
||||||
|
}
|
||||||
|
|
||||||
rpl::producer<TextWithEntities> PeerShortInfoBox::aboutValue() const {
|
rpl::producer<TextWithEntities> PeerShortInfoBox::aboutValue() const {
|
||||||
return _fields.value() | rpl::map([](const PeerShortInfoFields &fields) {
|
return _fields.value() | rpl::map([](const PeerShortInfoFields &fields) {
|
||||||
return fields.about;
|
return fields.about;
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "data/data_birthday.h"
|
||||||
#include "ui/layers/box_content.h"
|
#include "ui/layers/box_content.h"
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
|
@ -40,6 +41,7 @@ struct PeerShortInfoFields {
|
||||||
QString link;
|
QString link;
|
||||||
TextWithEntities about;
|
TextWithEntities about;
|
||||||
QString username;
|
QString username;
|
||||||
|
Data::Birthday birthday;
|
||||||
bool isBio = false;
|
bool isBio = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -171,6 +173,8 @@ private:
|
||||||
[[nodiscard]] rpl::producer<TextWithEntities> linkValue() const;
|
[[nodiscard]] rpl::producer<TextWithEntities> linkValue() const;
|
||||||
[[nodiscard]] rpl::producer<QString> phoneValue() const;
|
[[nodiscard]] rpl::producer<QString> phoneValue() const;
|
||||||
[[nodiscard]] rpl::producer<QString> usernameValue() const;
|
[[nodiscard]] rpl::producer<QString> usernameValue() const;
|
||||||
|
[[nodiscard]] rpl::producer<QString> birthdayLabel() const;
|
||||||
|
[[nodiscard]] rpl::producer<QString> birthdayValue() const;
|
||||||
[[nodiscard]] rpl::producer<TextWithEntities> aboutValue() const;
|
[[nodiscard]] rpl::producer<TextWithEntities> aboutValue() const;
|
||||||
|
|
||||||
const style::ShortInfoBox &_st;
|
const style::ShortInfoBox &_st;
|
||||||
|
|
|
@ -203,7 +203,8 @@ void ProcessFullPhoto(
|
||||||
(UpdateFlag::Name
|
(UpdateFlag::Name
|
||||||
| UpdateFlag::PhoneNumber
|
| UpdateFlag::PhoneNumber
|
||||||
| UpdateFlag::Username
|
| UpdateFlag::Username
|
||||||
| UpdateFlag::About)
|
| UpdateFlag::About
|
||||||
|
| UpdateFlag::Birthday)
|
||||||
) | rpl::map([=] {
|
) | rpl::map([=] {
|
||||||
const auto user = peer->asUser();
|
const auto user = peer->asUser();
|
||||||
const auto username = peer->userName();
|
const auto username = peer->userName();
|
||||||
|
@ -217,6 +218,7 @@ void ProcessFullPhoto(
|
||||||
.username = ((user && !username.isEmpty())
|
.username = ((user && !username.isEmpty())
|
||||||
? ('@' + username)
|
? ('@' + username)
|
||||||
: QString()),
|
: QString()),
|
||||||
|
.birthday = user ? user->birthday() : Data::Birthday(),
|
||||||
.isBio = (user && !user->isBot()),
|
.isBio = (user && !user->isBot()),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,6 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "data/data_birthday.h"
|
#include "data/data_birthday.h"
|
||||||
|
|
||||||
|
#include "base/timer_rpl.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDate>
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -66,5 +71,62 @@ int Birthday::year() const {
|
||||||
return _value / 10000;
|
return _value / 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString BirthdayText(Birthday date) {
|
||||||
|
if (const auto year = date.year()) {
|
||||||
|
return tr::lng_month_day_year(
|
||||||
|
tr::now,
|
||||||
|
lt_month,
|
||||||
|
Lang::MonthSmall(date.month())(tr::now),
|
||||||
|
lt_day,
|
||||||
|
QString::number(date.day()),
|
||||||
|
lt_year,
|
||||||
|
QString::number(year));
|
||||||
|
} else if (date) {
|
||||||
|
return tr::lng_month_day(
|
||||||
|
tr::now,
|
||||||
|
lt_month,
|
||||||
|
Lang::MonthSmall(date.month())(tr::now),
|
||||||
|
lt_day,
|
||||||
|
QString::number(date.day()));
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BirthdayCake() {
|
||||||
|
return QString::fromUtf8("\xf0\x9f\x8e\x82");
|
||||||
|
}
|
||||||
|
|
||||||
|
int BirthdayAge(Birthday date) {
|
||||||
|
if (!date.year()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const auto now = QDate::currentDate();
|
||||||
|
const auto day = QDate(date.year(), date.month(), date.day());
|
||||||
|
if (!day.isValid() || day >= now) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto age = now.year() - date.year();
|
||||||
|
if (now < QDate(date.year() + age, date.month(), date.day())) {
|
||||||
|
--age;
|
||||||
|
}
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsBirthdayToday(Birthday date) {
|
||||||
|
if (!date) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto now = QDate::currentDate();
|
||||||
|
return date.day() == now.day() && date.month() == now.month();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> IsBirthdayTodayValue(Birthday date) {
|
||||||
|
return rpl::single() | rpl::then(base::timer_each(
|
||||||
|
60 * crl::time(1000)
|
||||||
|
)) | rpl::map([=] {
|
||||||
|
return IsBirthdayToday(date);
|
||||||
|
}) | rpl::distinct_until_changed();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
|
|
|
@ -38,4 +38,10 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] QString BirthdayText(Birthday date);
|
||||||
|
[[nodiscard]] QString BirthdayCake();
|
||||||
|
[[nodiscard]] int BirthdayAge(Birthday date);
|
||||||
|
[[nodiscard]] bool IsBirthdayToday(Birthday date);
|
||||||
|
[[nodiscard]] rpl::producer<bool> IsBirthdayTodayValue(Birthday date);
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -1003,6 +1003,14 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
addInfoOneLine(
|
||||||
|
BirthdayLabelText(BirthdayValue(user)),
|
||||||
|
BirthdayValueText(
|
||||||
|
BirthdayValue(user)
|
||||||
|
) | Ui::Text::ToWithEntities(),
|
||||||
|
tr::lng_mediaview_copy(tr::now),
|
||||||
|
st::infoProfileLabeledUsernamePadding);
|
||||||
|
|
||||||
tracker.track(result->add(CreateWorkingHours(result, user)));
|
tracker.track(result->add(CreateWorkingHours(result, user)));
|
||||||
|
|
||||||
auto locationText = user->session().changes().peerFlagsValue(
|
auto locationText = user->session().changes().peerFlagsValue(
|
||||||
|
|
|
@ -635,5 +635,48 @@ rpl::producer<DocumentId> EmojiStatusIdValue(not_null<PeerData*> peer) {
|
||||||
) | rpl::map([=] { return peer->emojiStatusId(); });
|
) | rpl::map([=] { return peer->emojiStatusId(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<QString> BirthdayLabelText(
|
||||||
|
rpl::producer<Data::Birthday> birthday) {
|
||||||
|
return std::move(birthday) | rpl::map([](Data::Birthday value) {
|
||||||
|
return rpl::conditional(
|
||||||
|
Data::IsBirthdayTodayValue(value),
|
||||||
|
tr::lng_info_birthday_today_label(),
|
||||||
|
tr::lng_info_birthday_label());
|
||||||
|
}) | rpl::flatten_latest();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<QString> BirthdayValueText(
|
||||||
|
rpl::producer<Data::Birthday> birthday) {
|
||||||
|
return std::move(
|
||||||
|
birthday
|
||||||
|
) | rpl::map([](Data::Birthday value) -> rpl::producer<QString> {
|
||||||
|
if (!value) {
|
||||||
|
return rpl::single(QString());
|
||||||
|
}
|
||||||
|
return Data::IsBirthdayTodayValue(
|
||||||
|
value
|
||||||
|
) | 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);
|
||||||
|
}
|
||||||
|
if (today) {
|
||||||
|
text = tr::lng_info_birthday_today(
|
||||||
|
tr::now,
|
||||||
|
lt_emoji,
|
||||||
|
Data::BirthdayCake(),
|
||||||
|
lt_date,
|
||||||
|
text);
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
});
|
||||||
|
}) | rpl::flatten_latest();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Profile
|
} // namespace Profile
|
||||||
} // namespace Info
|
} // namespace Info
|
||||||
|
|
|
@ -121,4 +121,9 @@ enum class BadgeType;
|
||||||
[[nodiscard]] rpl::producer<DocumentId> EmojiStatusIdValue(
|
[[nodiscard]] rpl::producer<DocumentId> EmojiStatusIdValue(
|
||||||
not_null<PeerData*> peer);
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<QString> BirthdayLabelText(
|
||||||
|
rpl::producer<Data::Birthday> birthday);
|
||||||
|
[[nodiscard]] rpl::producer<QString> BirthdayValueText(
|
||||||
|
rpl::producer<Data::Birthday> birthday);
|
||||||
|
|
||||||
} // namespace Info::Profile
|
} // namespace Info::Profile
|
||||||
|
|
|
@ -367,23 +367,9 @@ void SetupBirthday(
|
||||||
Info::Profile::BirthdayValue(self),
|
Info::Profile::BirthdayValue(self),
|
||||||
tr::lng_settings_birthday_add()
|
tr::lng_settings_birthday_add()
|
||||||
) | rpl::map([](Data::Birthday birthday, const QString &add) {
|
) | rpl::map([](Data::Birthday birthday, const QString &add) {
|
||||||
const auto wrap = &Ui::Text::WithEntities;
|
const auto text = Data::BirthdayText(birthday);
|
||||||
if (const auto year = birthday.year()) {
|
if (!text.isEmpty()) {
|
||||||
return wrap(tr::lng_month_day_year(
|
return TextWithEntities{ text };
|
||||||
tr::now,
|
|
||||||
lt_month,
|
|
||||||
Lang::MonthSmall(birthday.month())(tr::now),
|
|
||||||
lt_day,
|
|
||||||
QString::number(birthday.day()),
|
|
||||||
lt_year,
|
|
||||||
QString::number(year)));
|
|
||||||
} else if (birthday) {
|
|
||||||
return wrap(tr::lng_month_day(
|
|
||||||
tr::now,
|
|
||||||
lt_month,
|
|
||||||
Lang::MonthSmall(birthday.month())(tr::now),
|
|
||||||
lt_day,
|
|
||||||
QString::number(birthday.day())));
|
|
||||||
}
|
}
|
||||||
auto result = TextWithEntities{ add };
|
auto result = TextWithEntities{ add };
|
||||||
result.entities.push_back({
|
result.entities.push_back({
|
||||||
|
|
Loading…
Add table
Reference in a new issue