Don't use double-badge in profile, use two.

This commit is contained in:
John Preston 2025-01-14 11:25:56 +04:00
parent e9e493707b
commit 6d7abd1718
8 changed files with 91 additions and 60 deletions

View file

@ -251,7 +251,20 @@ struct StatusFields {
}
Unexpected("Peer type in ChatPreview Item.");
});
}
[[nodiscard]] rpl::producer<Info::Profile::Badge::Content> ContentForPeer(
not_null<PeerData*> peer) {
using namespace Info::Profile;
return rpl::combine(
BadgeContentForPeer(peer),
VerifiedContentForPeer(peer)
) | rpl::map([](Badge::Content &&content, Badge::Content &&verified) {
if (verified.badge == BadgeType::Verified) {
content.badge = BadgeType::Verified;
}
return content;
});
}
Item::Item(not_null<Ui::RpWidget*> parent, not_null<Data::Thread*> thread)
@ -274,7 +287,8 @@ Item::Item(not_null<Ui::RpWidget*> parent, not_null<Data::Thread*> thread)
, _badge(
_top.get(),
st::settingsInfoPeerBadge,
_peer,
_session,
ContentForPeer(_peer),
nullptr,
nullptr,
1) {

View file

@ -24,22 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Info::Profile {
namespace {
[[nodiscard]] rpl::producer<Badge::Content> ContentForPeer(
not_null<PeerData*> peer) {
const auto statusOnlyForPremium = peer->isUser();
return rpl::combine(
BadgeValue(peer),
EmojiStatusIdValue(peer)
) | rpl::map([=](BadgeType badge, EmojiStatusId emojiStatusId) {
if (statusOnlyForPremium && badge != BadgeType::Premium) {
emojiStatusId = EmojiStatusId();
} else if (emojiStatusId && badge == BadgeType::None) {
badge = BadgeType::Premium;
}
return Badge::Content{ badge, emojiStatusId };
});
}
[[nodiscard]] bool HasPremiumClick(const Badge::Content &content) {
return content.badge == BadgeType::Premium
|| (content.badge == BadgeType::Verified && content.emojiStatusId);
@ -47,25 +31,6 @@ namespace {
} // namespace
Badge::Badge(
not_null<QWidget*> parent,
const style::InfoPeerBadge &st,
not_null<PeerData*> peer,
EmojiStatusPanel *emojiStatusPanel,
Fn<bool()> animationPaused,
int customStatusLoopsLimit,
base::flags<BadgeType> allowed)
: Badge(
parent,
st,
&peer->session(),
ContentForPeer(peer),
emojiStatusPanel,
std::move(animationPaused),
customStatusLoopsLimit,
allowed) {
}
Badge::Badge(
not_null<QWidget*> parent,
const style::InfoPeerBadge &st,
@ -237,4 +202,32 @@ Data::CustomEmojiSizeTag Badge::sizeTag() const {
: SizeTag::Normal;
}
rpl::producer<Badge::Content> BadgeContentForPeer(not_null<PeerData*> peer) {
const auto statusOnlyForPremium = peer->isUser();
return rpl::combine(
BadgeValue(peer),
EmojiStatusIdValue(peer)
) | rpl::map([=](BadgeType badge, EmojiStatusId emojiStatusId) {
if (badge == BadgeType::Verified) {
badge = BadgeType::None;
}
if (statusOnlyForPremium && badge != BadgeType::Premium) {
emojiStatusId = EmojiStatusId();
} else if (emojiStatusId && badge == BadgeType::None) {
badge = BadgeType::Premium;
}
return Badge::Content{ badge, emojiStatusId };
});
}
rpl::producer<Badge::Content> VerifiedContentForPeer(
not_null<PeerData*> peer) {
return BadgeValue(peer) | rpl::map([=](BadgeType badge) {
if (badge != BadgeType::Verified) {
badge = BadgeType::None;
}
return Badge::Content{ badge };
});
}
} // namespace Info::Profile

View file

@ -47,16 +47,6 @@ inline constexpr bool is_flag_type(BadgeType) { return true; }
class Badge final {
public:
Badge(
not_null<QWidget*> parent,
const style::InfoPeerBadge &st,
not_null<PeerData*> peer,
EmojiStatusPanel *emojiStatusPanel,
Fn<bool()> animationPaused,
int customStatusLoopsLimit = 0,
base::flags<BadgeType> allowed
= base::flags<BadgeType>::from_raw(-1));
struct Content {
BadgeType badge = BadgeType::None;
EmojiStatusId emojiStatusId;
@ -103,4 +93,9 @@ private:
};
[[nodiscard]] rpl::producer<Badge::Content> BadgeContentForPeer(
not_null<PeerData*> peer);
[[nodiscard]] rpl::producer<Badge::Content> VerifiedContentForPeer(
not_null<PeerData*> peer);
} // namespace Info::Profile

View file

@ -303,7 +303,7 @@ Cover::Cover(
std::move(title)) {
}
[[nodiscard]] rpl::producer<Badge::Content> VerifyBadgeForPeer(
[[nodiscard]] rpl::producer<Badge::Content> BotVerifyBadgeForPeer(
not_null<PeerData*> peer) {
return peer->session().changes().peerFlagsValue(
peer,
@ -332,12 +332,12 @@ Cover::Cover(
, _emojiStatusPanel(peer->isSelf()
? std::make_unique<EmojiStatusPanel>()
: nullptr)
, _verify(
, _botVerify(
std::make_unique<Badge>(
this,
st::infoPeerBadge,
&peer->session(),
VerifyBadgeForPeer(peer),
BotVerifyBadgeForPeer(peer),
nullptr,
[=] {
return controller->isGifPausedAtLeastFor(
@ -347,7 +347,19 @@ Cover::Cover(
std::make_unique<Badge>(
this,
st::infoPeerBadge,
peer,
&peer->session(),
BadgeContentForPeer(peer),
_emojiStatusPanel.get(),
[=] {
return controller->isGifPausedAtLeastFor(
Window::GifPauseReason::Layer);
}))
, _verified(
std::make_unique<Badge>(
this,
st::infoPeerBadge,
&peer->session(),
VerifiedContentForPeer(peer),
_emojiStatusPanel.get(),
[=] {
return controller->isGifPausedAtLeastFor(
@ -395,8 +407,9 @@ Cover::Cover(
}
});
rpl::merge(
_verify->updated(),
_badge->updated()
_botVerify->updated(),
_badge->updated(),
_verified->updated()
) | rpl::start_with_next([=] {
refreshNameGeometry(width());
}, _name->lifetime());
@ -734,16 +747,24 @@ Cover::~Cover() {
void Cover::refreshNameGeometry(int newWidth) {
auto nameWidth = newWidth - _st.nameLeft - _st.rightSkip;
if (const auto widget = _badge->widget()) {
nameWidth -= st::infoVerifiedCheckPosition.x() + widget->width();
const auto verifiedWidget = _verified->widget();
const auto badgeWidget = _badge->widget();
if (verifiedWidget) {
nameWidth -= verifiedWidget->width();
}
if (badgeWidget) {
nameWidth -= badgeWidget->width();
}
if (verifiedWidget || badgeWidget) {
nameWidth -= st::infoVerifiedCheckPosition.x();
}
auto nameLeft = _st.nameLeft;
const auto badgeTop = _st.nameTop;
const auto badgeBottom = _st.nameTop + _name->height();
const auto margins = LargeCustomEmojiMargins();
_verify->move(nameLeft - margins.left(), badgeTop, badgeBottom);
if (const auto widget = _verify->widget()) {
_botVerify->move(nameLeft - margins.left(), badgeTop, badgeBottom);
if (const auto widget = _botVerify->widget()) {
const auto skip = widget->width()
+ st::infoVerifiedCheckPosition.x();
nameLeft += skip;
@ -753,6 +774,10 @@ void Cover::refreshNameGeometry(int newWidth) {
_name->moveToLeft(nameLeft, _st.nameTop, newWidth);
const auto badgeLeft = nameLeft + _name->width();
_badge->move(badgeLeft, badgeTop, badgeBottom);
_verified->move(
badgeLeft + (badgeWidget ? badgeWidget->width() : 0),
badgeTop,
badgeBottom);
}
void Cover::refreshStatusGeometry(int newWidth) {

View file

@ -147,8 +147,9 @@ private:
const not_null<Window::SessionController*> _controller;
const not_null<PeerData*> _peer;
const std::unique_ptr<EmojiStatusPanel> _emojiStatusPanel;
const std::unique_ptr<Badge> _verify;
const std::unique_ptr<Badge> _botVerify;
const std::unique_ptr<Badge> _badge;
const std::unique_ptr<Badge> _verified;
rpl::variable<int> _onlineCount;
const object_ptr<Ui::UserpicButton> _userpic;

View file

@ -104,7 +104,8 @@ ComposedBadge::ComposedBadge(
, _badge(
this,
st::settingsInfoPeerBadge,
session->user(),
session,
Info::Profile::BadgeContentForPeer(session->user()),
nullptr,
std::move(animationPaused),
kPlayStatusLimit,

View file

@ -120,7 +120,8 @@ Cover::Cover(
, _badge(
this,
st::infoPeerBadge,
user,
&user->session(),
Info::Profile::BadgeContentForPeer(user),
&_emojiStatusPanel,
[=] {
return controller->isGifPausedAtLeastFor(

View file

@ -391,7 +391,8 @@ MainMenu::MainMenu(
, _badge(std::make_unique<Info::Profile::Badge>(
this,
st::settingsInfoPeerBadge,
controller->session().user(),
&controller->session(),
Info::Profile::BadgeContentForPeer(controller->session().user()),
_emojiStatusPanel.get(),
[=] { return controller->isGifPausedAtLeastFor(GifPauseReason::Layer); },
kPlayStatusLimit,