Improve verified badge display.
BIN
Telegram/Resources/art/verified_bg.webp
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Telegram/Resources/art/verified_fg.webp
Normal file
After Width: | Height: | Size: 500 B |
Before Width: | Height: | Size: 248 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 329 B After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 433 B After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 398 B After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 672 B After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1,001 B After Width: | Height: | Size: 1.9 KiB |
|
@ -34,6 +34,8 @@
|
|||
<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="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 prefix="/icons">
|
||||
<file alias="calls/hands.lottie">../../icons/calls/hands.lottie</file>
|
||||
|
|
|
@ -799,9 +799,6 @@ int PeerListRow::paintNameIconGetWidth(
|
|||
outerWidth,
|
||||
{
|
||||
.peer = peer(),
|
||||
.verified = &(selected
|
||||
? st::dialogsVerifiedIconOver
|
||||
: st::dialogsVerifiedIcon),
|
||||
.premium = &(selected
|
||||
? st::dialogsPremiumIcon.over
|
||||
: st::dialogsPremiumIcon.icon),
|
||||
|
|
|
@ -31,6 +31,12 @@ namespace {
|
|||
|
||||
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
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
[[nodiscard]] uint64 LocalTgsStickerId(QStringView name) {
|
||||
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<DocumentData*> GenerateLocalSticker(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &name) {
|
||||
const auto path = u":/animations/"_q + name + u".tgs"_q;
|
||||
const QString &path) {
|
||||
auto task = FileLoadTask(
|
||||
session,
|
||||
path,
|
||||
|
@ -335,7 +334,7 @@ not_null<DocumentData*> GenerateLocalTgsSticker(
|
|||
{},
|
||||
false,
|
||||
nullptr,
|
||||
LocalTgsStickerId(name));
|
||||
LocalStickerId(path));
|
||||
task.process({ .generateGoodThumbnail = false });
|
||||
const auto result = task.peekResult();
|
||||
Assert(result != nullptr);
|
||||
|
@ -348,8 +347,18 @@ not_null<DocumentData*> GenerateLocalTgsSticker(
|
|||
document->setLocation(Core::FileLocation(path));
|
||||
|
||||
Ensures(document->sticker());
|
||||
Ensures(document->sticker()->isLottie());
|
||||
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
|
||||
|
|
|
@ -130,6 +130,10 @@ bool PaintStickerThumbnailPath(
|
|||
not_null<DocumentData*> document,
|
||||
QSize box);
|
||||
|
||||
[[nodiscard]] not_null<DocumentData*> GenerateLocalSticker(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &path);
|
||||
|
||||
[[nodiscard]] not_null<DocumentData*> GenerateLocalTgsSticker(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &name);
|
||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "api/api_bot.h"
|
||||
#include "api/api_text_entities.h"
|
||||
#include "api/api_user_names.h"
|
||||
#include "chat_helpers/stickers_lottie.h"
|
||||
#include "core/application.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "core/mime_type.h" // Core::IsMimeSticker
|
||||
|
@ -353,11 +354,16 @@ Session::Session(not_null<Main::Session*> session)
|
|||
|
||||
Ui::VerifyDetails Session::verifiedByTelegram() {
|
||||
if (_verifiedByTelegramIconBgId.isEmpty()) {
|
||||
auto &manager = customEmojiManager();
|
||||
_verifiedByTelegramIconBgId = manager.registerInternalEmoji(
|
||||
st::dialogsVerifiedBg);
|
||||
_verifiedByTelegramIconFgId = manager.registerInternalEmoji(
|
||||
st::dialogsVerifiedFg);
|
||||
const auto bg = ChatHelpers::GenerateLocalSticker(
|
||||
_session,
|
||||
u":/gui/art/verified_bg.webp"_q);
|
||||
bg->overrideEmojiUsesTextColor(true);
|
||||
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 {
|
||||
.iconBgId = _verifiedByTelegramIconBgId,
|
||||
|
|
|
@ -409,6 +409,7 @@ dialogsLockIcon: ThreeStateIcon {
|
|||
|
||||
dialogsVerifiedBg: icon{{ "dialogs/dialogs_verified_star", dialogsVerifiedIconBg }};
|
||||
dialogsVerifiedFg: icon{{ "dialogs/dialogs_verified_check", dialogsVerifiedIconFg }};
|
||||
dialogsVerifiedPadding: margins(0px, 3px, 0px, 0px);
|
||||
dialogsVerifiedColors: VerifiedBadge {
|
||||
height: 20px;
|
||||
bg: dialogsVerifiedIconBg;
|
||||
|
@ -423,18 +424,6 @@ dialogsVerifiedColorsActive: VerifiedBadge(dialogsVerifiedColors) {
|
|||
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 {
|
||||
icon: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBg }};
|
||||
over: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBgOver }};
|
||||
|
|
|
@ -1398,11 +1398,6 @@ void InnerWidget::paintPeerSearchResult(
|
|||
context.width,
|
||||
{
|
||||
.peer = peer,
|
||||
.verified = (context.active
|
||||
? &st::dialogsVerifiedIconActive
|
||||
: context.selected
|
||||
? &st::dialogsVerifiedIconOver
|
||||
: &st::dialogsVerifiedIcon),
|
||||
.premium = &ThreeStateIcon(
|
||||
st::dialogsPremiumIcon,
|
||||
context.active,
|
||||
|
|
|
@ -732,11 +732,6 @@ void PaintRow(
|
|||
context.width,
|
||||
{
|
||||
.peer = from,
|
||||
.verified = (context.active
|
||||
? &st::dialogsVerifiedIconActive
|
||||
: context.selected
|
||||
? &st::dialogsVerifiedIconOver
|
||||
: &st::dialogsVerifiedIcon),
|
||||
.premium = &ThreeStateIcon(
|
||||
st::dialogsPremiumIcon,
|
||||
context.active,
|
||||
|
|
|
@ -589,7 +589,6 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
|||
width(),
|
||||
{
|
||||
.peer = namePeer,
|
||||
.verified = &st::dialogsVerifiedIcon,
|
||||
.premium = &st::dialogsPremiumIcon.icon,
|
||||
.scam = &st::attentionButtonFg,
|
||||
.premiumFg = &st::dialogsVerifiedIconBg,
|
||||
|
|
|
@ -22,7 +22,6 @@ InfoToggle {
|
|||
}
|
||||
|
||||
InfoPeerBadge {
|
||||
verified: icon;
|
||||
premium: icon;
|
||||
premiumFg: color;
|
||||
premiumInnerFg: color;
|
||||
|
@ -437,7 +436,6 @@ infoVerifiedCheck: icon {
|
|||
infoPremiumStar: icon {{ "profile_premium", profileVerifiedCheckBg }};
|
||||
|
||||
infoPeerBadge: InfoPeerBadge {
|
||||
verified: infoVerifiedCheck;
|
||||
premium: infoPremiumStar;
|
||||
premiumFg: profileVerifiedCheckBg;
|
||||
premiumInnerFg: profileVerifiedCheckFg;
|
||||
|
|
|
@ -35,7 +35,12 @@ namespace {
|
|||
} else if (emojiStatusId && badge == BadgeType::None) {
|
||||
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: {
|
||||
const auto id = _content.emojiStatusId;
|
||||
const auto innerId = _content.emojiStatusInnerId;
|
||||
if (id || innerId) {
|
||||
_emojiStatus = id
|
||||
if (!id.isEmpty() || !innerId.isEmpty()) {
|
||||
_emojiStatus = !id.isEmpty()
|
||||
? _session->data().customEmojiManager().create(
|
||||
id,
|
||||
[raw = _view.data()] { raw->update(); },
|
||||
sizeTag())
|
||||
: nullptr;
|
||||
_statusInner = innerId
|
||||
_statusInner = !innerId.isEmpty()
|
||||
? _session->data().customEmojiManager().create(
|
||||
innerId,
|
||||
[raw = _view.data()] { raw->update(); },
|
||||
|
@ -162,9 +167,7 @@ void Badge::setContent(Content content) {
|
|||
}
|
||||
}, _view->lifetime());
|
||||
} else {
|
||||
const auto icon = (_content.badge == BadgeType::Verified)
|
||||
? &_st.verified
|
||||
: &_st.premium;
|
||||
const auto icon = &_st.premium;
|
||||
_view->resize(icon->size());
|
||||
_view->paintRequest(
|
||||
) | rpl::start_with_next([=, check = _view.data()]{
|
||||
|
@ -224,9 +227,9 @@ void Badge::move(int left, int top, int bottom) {
|
|||
return;
|
||||
}
|
||||
const auto star = !_emojiStatus
|
||||
&& (_content.badge == BadgeType::Premium
|
||||
|| _content.badge == BadgeType::Verified);
|
||||
const auto fake = !_emojiStatus && !star;
|
||||
&& (_content.badge == BadgeType::Premium);
|
||||
const auto fake = (!_emojiStatus && !star)
|
||||
|| (_content.badge == BadgeType::Verified);
|
||||
const auto skip = fake ? 0 : _st.position.x();
|
||||
const auto badgeLeft = left + skip;
|
||||
const auto badgeTop = top
|
||||
|
|
|
@ -58,8 +58,8 @@ public:
|
|||
|
||||
struct Content {
|
||||
BadgeType badge = BadgeType::None;
|
||||
DocumentId emojiStatusId = 0;
|
||||
DocumentId emojiStatusInnerId = 0;
|
||||
QString emojiStatusId;
|
||||
QString emojiStatusInnerId;
|
||||
|
||||
friend inline constexpr bool operator==(Content, Content) = default;
|
||||
};
|
||||
|
|
|
@ -302,10 +302,8 @@ Cover::Cover(
|
|||
const auto details = peer->verifyDetails();
|
||||
return Badge::Content{
|
||||
.badge = details ? BadgeType::Verified : BadgeType::None,
|
||||
.emojiStatusId = details ? details->iconBgId.toULongLong() : 0,
|
||||
.emojiStatusInnerId = (details
|
||||
? details->iconFgId.toULongLong()
|
||||
: 0),
|
||||
.emojiStatusId = details ? details->iconBgId : QString(),
|
||||
.emojiStatusInnerId = details ? details->iconFgId : QString(),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -197,10 +197,6 @@ settingsInfoPhotoSkip: 7px;
|
|||
settingsInfoNameSkip: -1px;
|
||||
settingsInfoUploadLeft: 6px;
|
||||
settingsInfoPeerBadge: InfoPeerBadge {
|
||||
verified: icon {
|
||||
{ "dialogs/dialogs_verified_star", dialogsVerifiedIconBg },
|
||||
{ "dialogs/dialogs_verified_check", dialogsVerifiedIconFg },
|
||||
};
|
||||
premium: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBg }};
|
||||
premiumFg: dialogsVerifiedIconBg;
|
||||
premiumInnerFg: dialogsVerifiedIconFg;
|
||||
|
|