Improve verified badge display.

This commit is contained in:
John Preston 2024-12-20 10:38:06 +04:00
parent 0363421862
commit 5c301353ec
22 changed files with 55 additions and 64 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 433 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 398 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 672 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,001 B

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -34,6 +34,8 @@
<file alias="topic_icons/general.svg">../../art/topic_icons/general.svg</file> <file alias="topic_icons/general.svg">../../art/topic_icons/general.svg</file>
<file alias="links_subscription.svg">../../icons/info/edit/links_subscription.svg</file> <file alias="links_subscription.svg">../../icons/info/edit/links_subscription.svg</file>
<file alias="plane_white.svg">../../icons/plane_white.svg</file> <file alias="plane_white.svg">../../icons/plane_white.svg</file>
<file alias="art/verified_bg.webp">../../art/verified_bg.webp</file>
<file alias="art/verified_fg.webp">../../art/verified_fg.webp</file>
</qresource> </qresource>
<qresource prefix="/icons"> <qresource prefix="/icons">
<file alias="calls/hands.lottie">../../icons/calls/hands.lottie</file> <file alias="calls/hands.lottie">../../icons/calls/hands.lottie</file>

View file

@ -799,9 +799,6 @@ int PeerListRow::paintNameIconGetWidth(
outerWidth, outerWidth,
{ {
.peer = peer(), .peer = peer(),
.verified = &(selected
? st::dialogsVerifiedIconOver
: st::dialogsVerifiedIcon),
.premium = &(selected .premium = &(selected
? st::dialogsPremiumIcon.over ? st::dialogsPremiumIcon.over
: st::dialogsPremiumIcon.icon), : st::dialogsPremiumIcon.icon),

View file

@ -31,6 +31,12 @@ namespace {
constexpr auto kDontCacheLottieAfterArea = 512 * 512; constexpr auto kDontCacheLottieAfterArea = 512 * 512;
[[nodiscard]] uint64 LocalStickerId(QStringView name) {
auto full = u"local_sticker:"_q;
full.append(name);
return XXH64(full.data(), full.size() * sizeof(QChar), 0);
}
} // namespace } // namespace
uint8 LottieCacheKeyShift(uint8 replacementsTag, StickerLottieSize sizeTag) { uint8 LottieCacheKeyShift(uint8 replacementsTag, StickerLottieSize sizeTag) {
@ -315,16 +321,9 @@ QSize ComputeStickerSize(not_null<DocumentData*> document, QSize box) {
return HistoryView::NonEmptySize(request.size(dimensions, 8) / ratio); return HistoryView::NonEmptySize(request.size(dimensions, 8) / ratio);
} }
[[nodiscard]] uint64 LocalTgsStickerId(QStringView name) { not_null<DocumentData*> GenerateLocalSticker(
auto full = u"local_tgs_sticker:"_q;
full.append(name);
return XXH64(full.data(), full.size() * sizeof(QChar), 0);
}
not_null<DocumentData*> GenerateLocalTgsSticker(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const QString &name) { const QString &path) {
const auto path = u":/animations/"_q + name + u".tgs"_q;
auto task = FileLoadTask( auto task = FileLoadTask(
session, session,
path, path,
@ -335,7 +334,7 @@ not_null<DocumentData*> GenerateLocalTgsSticker(
{}, {},
false, false,
nullptr, nullptr,
LocalTgsStickerId(name)); LocalStickerId(path));
task.process({ .generateGoodThumbnail = false }); task.process({ .generateGoodThumbnail = false });
const auto result = task.peekResult(); const auto result = task.peekResult();
Assert(result != nullptr); Assert(result != nullptr);
@ -348,8 +347,18 @@ not_null<DocumentData*> GenerateLocalTgsSticker(
document->setLocation(Core::FileLocation(path)); document->setLocation(Core::FileLocation(path));
Ensures(document->sticker()); Ensures(document->sticker());
Ensures(document->sticker()->isLottie());
return document; return document;
} }
not_null<DocumentData*> GenerateLocalTgsSticker(
not_null<Main::Session*> session,
const QString &name) {
const auto result = GenerateLocalSticker(
session,
u":/animations/"_q + name + u".tgs"_q);
Ensures(result->sticker()->isLottie());
return result;
}
} // namespace ChatHelpers } // namespace ChatHelpers

View file

@ -130,6 +130,10 @@ bool PaintStickerThumbnailPath(
not_null<DocumentData*> document, not_null<DocumentData*> document,
QSize box); QSize box);
[[nodiscard]] not_null<DocumentData*> GenerateLocalSticker(
not_null<Main::Session*> session,
const QString &path);
[[nodiscard]] not_null<DocumentData*> GenerateLocalTgsSticker( [[nodiscard]] not_null<DocumentData*> GenerateLocalTgsSticker(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const QString &name); const QString &name);

View file

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_bot.h" #include "api/api_bot.h"
#include "api/api_text_entities.h" #include "api/api_text_entities.h"
#include "api/api_user_names.h" #include "api/api_user_names.h"
#include "chat_helpers/stickers_lottie.h"
#include "core/application.h" #include "core/application.h"
#include "core/core_settings.h" #include "core/core_settings.h"
#include "core/mime_type.h" // Core::IsMimeSticker #include "core/mime_type.h" // Core::IsMimeSticker
@ -353,11 +354,16 @@ Session::Session(not_null<Main::Session*> session)
Ui::VerifyDetails Session::verifiedByTelegram() { Ui::VerifyDetails Session::verifiedByTelegram() {
if (_verifiedByTelegramIconBgId.isEmpty()) { if (_verifiedByTelegramIconBgId.isEmpty()) {
auto &manager = customEmojiManager(); const auto bg = ChatHelpers::GenerateLocalSticker(
_verifiedByTelegramIconBgId = manager.registerInternalEmoji( _session,
st::dialogsVerifiedBg); u":/gui/art/verified_bg.webp"_q);
_verifiedByTelegramIconFgId = manager.registerInternalEmoji( bg->overrideEmojiUsesTextColor(true);
st::dialogsVerifiedFg); const auto fg = ChatHelpers::GenerateLocalSticker(
_session,
u":/gui/art/verified_fg.webp"_q);
fg->overrideEmojiUsesTextColor(true);
_verifiedByTelegramIconBgId = Data::SerializeCustomEmojiId(bg);
_verifiedByTelegramIconFgId = Data::SerializeCustomEmojiId(fg);
} }
return { return {
.iconBgId = _verifiedByTelegramIconBgId, .iconBgId = _verifiedByTelegramIconBgId,

View file

@ -409,6 +409,7 @@ dialogsLockIcon: ThreeStateIcon {
dialogsVerifiedBg: icon{{ "dialogs/dialogs_verified_star", dialogsVerifiedIconBg }}; dialogsVerifiedBg: icon{{ "dialogs/dialogs_verified_star", dialogsVerifiedIconBg }};
dialogsVerifiedFg: icon{{ "dialogs/dialogs_verified_check", dialogsVerifiedIconFg }}; dialogsVerifiedFg: icon{{ "dialogs/dialogs_verified_check", dialogsVerifiedIconFg }};
dialogsVerifiedPadding: margins(0px, 3px, 0px, 0px);
dialogsVerifiedColors: VerifiedBadge { dialogsVerifiedColors: VerifiedBadge {
height: 20px; height: 20px;
bg: dialogsVerifiedIconBg; bg: dialogsVerifiedIconBg;
@ -423,18 +424,6 @@ dialogsVerifiedColorsActive: VerifiedBadge(dialogsVerifiedColors) {
fg: dialogsVerifiedIconFgActive; fg: dialogsVerifiedIconFgActive;
} }
dialogsVerifiedIcon: icon {
{ "dialogs/dialogs_verified_star", dialogsVerifiedIconBg },
{ "dialogs/dialogs_verified_check", dialogsVerifiedIconFg },
};
dialogsVerifiedIconOver: icon {
{ "dialogs/dialogs_verified_star", dialogsVerifiedIconBgOver },
{ "dialogs/dialogs_verified_check", dialogsVerifiedIconFgOver },
};
dialogsVerifiedIconActive: icon {
{ "dialogs/dialogs_verified_star", dialogsVerifiedIconBgActive },
{ "dialogs/dialogs_verified_check", dialogsVerifiedIconFgActive },
};
dialogsPremiumIcon: ThreeStateIcon { dialogsPremiumIcon: ThreeStateIcon {
icon: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBg }}; icon: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBg }};
over: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBgOver }}; over: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBgOver }};

View file

@ -1398,11 +1398,6 @@ void InnerWidget::paintPeerSearchResult(
context.width, context.width,
{ {
.peer = peer, .peer = peer,
.verified = (context.active
? &st::dialogsVerifiedIconActive
: context.selected
? &st::dialogsVerifiedIconOver
: &st::dialogsVerifiedIcon),
.premium = &ThreeStateIcon( .premium = &ThreeStateIcon(
st::dialogsPremiumIcon, st::dialogsPremiumIcon,
context.active, context.active,

View file

@ -732,11 +732,6 @@ void PaintRow(
context.width, context.width,
{ {
.peer = from, .peer = from,
.verified = (context.active
? &st::dialogsVerifiedIconActive
: context.selected
? &st::dialogsVerifiedIconOver
: &st::dialogsVerifiedIcon),
.premium = &ThreeStateIcon( .premium = &ThreeStateIcon(
st::dialogsPremiumIcon, st::dialogsPremiumIcon,
context.active, context.active,

View file

@ -589,7 +589,6 @@ void TopBarWidget::paintTopBar(Painter &p) {
width(), width(),
{ {
.peer = namePeer, .peer = namePeer,
.verified = &st::dialogsVerifiedIcon,
.premium = &st::dialogsPremiumIcon.icon, .premium = &st::dialogsPremiumIcon.icon,
.scam = &st::attentionButtonFg, .scam = &st::attentionButtonFg,
.premiumFg = &st::dialogsVerifiedIconBg, .premiumFg = &st::dialogsVerifiedIconBg,

View file

@ -22,7 +22,6 @@ InfoToggle {
} }
InfoPeerBadge { InfoPeerBadge {
verified: icon;
premium: icon; premium: icon;
premiumFg: color; premiumFg: color;
premiumInnerFg: color; premiumInnerFg: color;
@ -437,7 +436,6 @@ infoVerifiedCheck: icon {
infoPremiumStar: icon {{ "profile_premium", profileVerifiedCheckBg }}; infoPremiumStar: icon {{ "profile_premium", profileVerifiedCheckBg }};
infoPeerBadge: InfoPeerBadge { infoPeerBadge: InfoPeerBadge {
verified: infoVerifiedCheck;
premium: infoPremiumStar; premium: infoPremiumStar;
premiumFg: profileVerifiedCheckBg; premiumFg: profileVerifiedCheckBg;
premiumInnerFg: profileVerifiedCheckFg; premiumInnerFg: profileVerifiedCheckFg;

View file

@ -35,7 +35,12 @@ namespace {
} else if (emojiStatusId && badge == BadgeType::None) { } else if (emojiStatusId && badge == BadgeType::None) {
badge = BadgeType::Premium; badge = BadgeType::Premium;
} }
return Badge::Content{ badge, emojiStatusId }; return Badge::Content{
badge,
(emojiStatusId
? Data::SerializeCustomEmojiId(emojiStatusId)
: QString()),
};
}); });
} }
@ -115,14 +120,14 @@ void Badge::setContent(Content content) {
case BadgeType::Premium: { case BadgeType::Premium: {
const auto id = _content.emojiStatusId; const auto id = _content.emojiStatusId;
const auto innerId = _content.emojiStatusInnerId; const auto innerId = _content.emojiStatusInnerId;
if (id || innerId) { if (!id.isEmpty() || !innerId.isEmpty()) {
_emojiStatus = id _emojiStatus = !id.isEmpty()
? _session->data().customEmojiManager().create( ? _session->data().customEmojiManager().create(
id, id,
[raw = _view.data()] { raw->update(); }, [raw = _view.data()] { raw->update(); },
sizeTag()) sizeTag())
: nullptr; : nullptr;
_statusInner = innerId _statusInner = !innerId.isEmpty()
? _session->data().customEmojiManager().create( ? _session->data().customEmojiManager().create(
innerId, innerId,
[raw = _view.data()] { raw->update(); }, [raw = _view.data()] { raw->update(); },
@ -162,9 +167,7 @@ void Badge::setContent(Content content) {
} }
}, _view->lifetime()); }, _view->lifetime());
} else { } else {
const auto icon = (_content.badge == BadgeType::Verified) const auto icon = &_st.premium;
? &_st.verified
: &_st.premium;
_view->resize(icon->size()); _view->resize(icon->size());
_view->paintRequest( _view->paintRequest(
) | rpl::start_with_next([=, check = _view.data()]{ ) | rpl::start_with_next([=, check = _view.data()]{
@ -224,9 +227,9 @@ void Badge::move(int left, int top, int bottom) {
return; return;
} }
const auto star = !_emojiStatus const auto star = !_emojiStatus
&& (_content.badge == BadgeType::Premium && (_content.badge == BadgeType::Premium);
|| _content.badge == BadgeType::Verified); const auto fake = (!_emojiStatus && !star)
const auto fake = !_emojiStatus && !star; || (_content.badge == BadgeType::Verified);
const auto skip = fake ? 0 : _st.position.x(); const auto skip = fake ? 0 : _st.position.x();
const auto badgeLeft = left + skip; const auto badgeLeft = left + skip;
const auto badgeTop = top const auto badgeTop = top

View file

@ -58,8 +58,8 @@ public:
struct Content { struct Content {
BadgeType badge = BadgeType::None; BadgeType badge = BadgeType::None;
DocumentId emojiStatusId = 0; QString emojiStatusId;
DocumentId emojiStatusInnerId = 0; QString emojiStatusInnerId;
friend inline constexpr bool operator==(Content, Content) = default; friend inline constexpr bool operator==(Content, Content) = default;
}; };

View file

@ -302,10 +302,8 @@ Cover::Cover(
const auto details = peer->verifyDetails(); const auto details = peer->verifyDetails();
return Badge::Content{ return Badge::Content{
.badge = details ? BadgeType::Verified : BadgeType::None, .badge = details ? BadgeType::Verified : BadgeType::None,
.emojiStatusId = details ? details->iconBgId.toULongLong() : 0, .emojiStatusId = details ? details->iconBgId : QString(),
.emojiStatusInnerId = (details .emojiStatusInnerId = details ? details->iconFgId : QString(),
? details->iconFgId.toULongLong()
: 0),
}; };
}); });
} }

View file

@ -197,10 +197,6 @@ settingsInfoPhotoSkip: 7px;
settingsInfoNameSkip: -1px; settingsInfoNameSkip: -1px;
settingsInfoUploadLeft: 6px; settingsInfoUploadLeft: 6px;
settingsInfoPeerBadge: InfoPeerBadge { settingsInfoPeerBadge: InfoPeerBadge {
verified: icon {
{ "dialogs/dialogs_verified_star", dialogsVerifiedIconBg },
{ "dialogs/dialogs_verified_check", dialogsVerifiedIconFg },
};
premium: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBg }}; premium: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBg }};
premiumFg: dialogsVerifiedIconBg; premiumFg: dialogsVerifiedIconBg;
premiumInnerFg: dialogsVerifiedIconFg; premiumInnerFg: dialogsVerifiedIconFg;