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."); 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) 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( , _badge(
_top.get(), _top.get(),
st::settingsInfoPeerBadge, st::settingsInfoPeerBadge,
_peer, _session,
ContentForPeer(_peer),
nullptr, nullptr,
nullptr, nullptr,
1) { 1) {

View file

@ -24,22 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Info::Profile { namespace Info::Profile {
namespace { 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) { [[nodiscard]] bool HasPremiumClick(const Badge::Content &content) {
return content.badge == BadgeType::Premium return content.badge == BadgeType::Premium
|| (content.badge == BadgeType::Verified && content.emojiStatusId); || (content.badge == BadgeType::Verified && content.emojiStatusId);
@ -47,25 +31,6 @@ namespace {
} // 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( Badge::Badge(
not_null<QWidget*> parent, not_null<QWidget*> parent,
const style::InfoPeerBadge &st, const style::InfoPeerBadge &st,
@ -237,4 +202,32 @@ Data::CustomEmojiSizeTag Badge::sizeTag() const {
: SizeTag::Normal; : 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 } // namespace Info::Profile

View file

@ -47,16 +47,6 @@ inline constexpr bool is_flag_type(BadgeType) { return true; }
class Badge final { class Badge final {
public: 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 { struct Content {
BadgeType badge = BadgeType::None; BadgeType badge = BadgeType::None;
EmojiStatusId emojiStatusId; 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 } // namespace Info::Profile

View file

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

View file

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

View file

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

View file

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

View file

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