Return native verify icon to the right.

This commit is contained in:
John Preston 2024-12-31 17:18:59 +04:00
parent c23b533704
commit a7321c9beb
33 changed files with 167 additions and 233 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

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

View file

@ -1641,28 +1641,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_bot_verify_bot_submit" = "Verify Bot"; "lng_bot_verify_bot_submit" = "Verify Bot";
"lng_bot_verify_bot_sent" = "{name} has been notified and will receive your verification mark and description upon accepting."; "lng_bot_verify_bot_sent" = "{name} has been notified and will receive your verification mark and description upon accepting.";
"lng_bot_verify_bot_remove" = "This bot is already verified by you. Do you want to remove verification?"; "lng_bot_verify_bot_remove" = "This bot is already verified by you. Do you want to remove verification?";
"lng_bot_verify_bot_telegram" = "This bot is verified as official by the representatives of Telegram.";
"lng_bot_verify_user_title" = "Verify User"; "lng_bot_verify_user_title" = "Verify User";
"lng_bot_verify_user_text" = "Do you want to verify {name} with your verification mark and description?"; "lng_bot_verify_user_text" = "Do you want to verify {name} with your verification mark and description?";
"lng_bot_verify_user_about" = "You can customize your description for each account."; "lng_bot_verify_user_about" = "You can customize your description for each account.";
"lng_bot_verify_user_submit" = "Verify User"; "lng_bot_verify_user_submit" = "Verify User";
"lng_bot_verify_user_sent" = "{name} has been notified and will receive your verification mark and description upon accepting."; "lng_bot_verify_user_sent" = "{name} has been notified and will receive your verification mark and description upon accepting.";
"lng_bot_verify_user_remove" = "This account is already verified by you. Do you want to remove verification?"; "lng_bot_verify_user_remove" = "This account is already verified by you. Do you want to remove verification?";
"lng_bot_verify_user_telegram" = "This account is verified as official by the representatives of Telegram.";
"lng_bot_verify_channel_title" = "Verify Channel"; "lng_bot_verify_channel_title" = "Verify Channel";
"lng_bot_verify_channel_text" = "Do you want to verify {name} with your verification mark and description?"; "lng_bot_verify_channel_text" = "Do you want to verify {name} with your verification mark and description?";
"lng_bot_verify_channel_about" = "You can customize your description for each channel."; "lng_bot_verify_channel_about" = "You can customize your description for each channel.";
"lng_bot_verify_channel_submit" = "Verify Channel"; "lng_bot_verify_channel_submit" = "Verify Channel";
"lng_bot_verify_channel_sent" = "{name} has been notified and will receive your verification mark and description upon accepting."; "lng_bot_verify_channel_sent" = "{name} has been notified and will receive your verification mark and description upon accepting.";
"lng_bot_verify_channel_remove" = "This channel is already verified by you. Do you want to remove verification?"; "lng_bot_verify_channel_remove" = "This channel is already verified by you. Do you want to remove verification?";
"lng_bot_verify_channel_telegram" = "This channel is verified as official by the representatives of Telegram.";
"lng_bot_verify_group_title" = "Verify Group"; "lng_bot_verify_group_title" = "Verify Group";
"lng_bot_verify_group_text" = "Do you want to verify {name} with your verification mark and description?"; "lng_bot_verify_group_text" = "Do you want to verify {name} with your verification mark and description?";
"lng_bot_verify_group_about" = "You can customize your description for each group."; "lng_bot_verify_group_about" = "You can customize your description for each group.";
"lng_bot_verify_group_submit" = "Verify Group"; "lng_bot_verify_group_submit" = "Verify Group";
"lng_bot_verify_group_sent" = "{name} has been notified and will receive your verification mark and description upon accepting."; "lng_bot_verify_group_sent" = "{name} has been notified and will receive your verification mark and description upon accepting.";
"lng_bot_verify_group_remove" = "This group is already verified by you. Do you want to remove verification?"; "lng_bot_verify_group_remove" = "This group is already verified by you. Do you want to remove verification?";
"lng_bot_verify_group_telegram" = "This community is verified as official by the representatives of Telegram.";
"lng_bot_verify_description_label" = "Description"; "lng_bot_verify_description_label" = "Description";
"lng_bot_verify_remove_title" = "Remove verification"; "lng_bot_verify_remove_title" = "Remove verification";
"lng_bot_verify_remove_submit" = "Remove"; "lng_bot_verify_remove_submit" = "Remove";

View file

@ -34,8 +34,6 @@
<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

@ -570,7 +570,9 @@ ConfirmInviteBox::ChatInvite ConfirmInviteBox::Parse(
[[nodiscard]] Info::Profile::BadgeType ConfirmInviteBox::BadgeForInvite( [[nodiscard]] Info::Profile::BadgeType ConfirmInviteBox::BadgeForInvite(
const ChatInvite &invite) { const ChatInvite &invite) {
using Type = Info::Profile::BadgeType; using Type = Info::Profile::BadgeType;
return invite.isScam return invite.isVerified
? Type::Verified
: invite.isScam
? Type::Scam ? Type::Scam
: invite.isFake : invite.isFake
? Type::Fake ? Type::Fake

View file

@ -799,6 +799,9 @@ 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

@ -90,7 +90,7 @@ Main::Session &Controller::session() const {
void Controller::rowClicked(gsl::not_null<PeerListRow*> row) { void Controller::rowClicked(gsl::not_null<PeerListRow*> row) {
const auto peer = row->peer(); const auto peer = row->peer();
const auto details = peer->verifyDetails(); const auto details = peer->botVerifyDetails();
const auto already = details && (details->botId == peerToUser(_bot->id)); const auto already = details && (details->botId == peerToUser(_bot->id));
if (already) { if (already) {
confirmRemove(peer); confirmRemove(peer);
@ -141,7 +141,7 @@ void Controller::confirmAdd(not_null<PeerData*> peer) {
Ui::Text::Bold(peer->shortName()), Ui::Text::Bold(peer->shortName()),
Ui::Text::WithEntities), Ui::Text::WithEntities),
.duration = kSetupVerificationToastDuration, .duration = kSetupVerificationToastDuration,
}); });
} else { } else {
state->sent = false; state->sent = false;
show->showToast(error); show->showToast(error);
@ -253,7 +253,7 @@ object_ptr<Ui::BoxContent> MakeVerifyPeersBox(
return Box<PeerListBox>(std::move(controller), std::move(init)); return Box<PeerListBox>(std::move(controller), std::move(init));
} }
VerifyPhrases PeerVerifyPhrases(not_null<PeerData*> peer) { BotVerifyPhrases PeerVerifyPhrases(not_null<PeerData*> peer) {
if (const auto user = peer->asUser()) { if (const auto user = peer->asUser()) {
if (user->isBot()) { if (user->isBot()) {
return { return {
@ -263,7 +263,6 @@ VerifyPhrases PeerVerifyPhrases(not_null<PeerData*> peer) {
.submit = tr::lng_bot_verify_bot_submit, .submit = tr::lng_bot_verify_bot_submit,
.sent = tr::lng_bot_verify_bot_sent, .sent = tr::lng_bot_verify_bot_sent,
.remove = tr::lng_bot_verify_bot_remove, .remove = tr::lng_bot_verify_bot_remove,
.telegram = tr::lng_bot_verify_bot_telegram,
}; };
} else { } else {
return { return {
@ -273,7 +272,6 @@ VerifyPhrases PeerVerifyPhrases(not_null<PeerData*> peer) {
.submit = tr::lng_bot_verify_user_submit, .submit = tr::lng_bot_verify_user_submit,
.sent = tr::lng_bot_verify_user_sent, .sent = tr::lng_bot_verify_user_sent,
.remove = tr::lng_bot_verify_user_remove, .remove = tr::lng_bot_verify_user_remove,
.telegram = tr::lng_bot_verify_user_telegram,
}; };
} }
} else if (peer->isBroadcast()) { } else if (peer->isBroadcast()) {
@ -284,7 +282,6 @@ VerifyPhrases PeerVerifyPhrases(not_null<PeerData*> peer) {
.submit = tr::lng_bot_verify_channel_submit, .submit = tr::lng_bot_verify_channel_submit,
.sent = tr::lng_bot_verify_channel_sent, .sent = tr::lng_bot_verify_channel_sent,
.remove = tr::lng_bot_verify_channel_remove, .remove = tr::lng_bot_verify_channel_remove,
.telegram = tr::lng_bot_verify_channel_telegram,
}; };
} }
return { return {
@ -294,6 +291,5 @@ VerifyPhrases PeerVerifyPhrases(not_null<PeerData*> peer) {
.submit = tr::lng_bot_verify_group_submit, .submit = tr::lng_bot_verify_group_submit,
.sent = tr::lng_bot_verify_group_sent, .sent = tr::lng_bot_verify_group_sent,
.remove = tr::lng_bot_verify_group_remove, .remove = tr::lng_bot_verify_group_remove,
.telegram = tr::lng_bot_verify_group_telegram,
}; };
} }

View file

@ -25,13 +25,12 @@ class SessionController;
not_null<Window::SessionController*> window, not_null<Window::SessionController*> window,
not_null<UserData*> bot); not_null<UserData*> bot);
struct VerifyPhrases { struct BotVerifyPhrases {
tr::phrase<> title; tr::phrase<> title;
tr::phrase<lngtag_name> text; tr::phrase<lngtag_name> text;
tr::phrase<> about; tr::phrase<> about;
tr::phrase<> submit; tr::phrase<> submit;
tr::phrase<lngtag_name> sent; tr::phrase<lngtag_name> sent;
tr::phrase<> remove; tr::phrase<> remove;
tr::phrase<> telegram;
}; };
[[nodiscard]] VerifyPhrases PeerVerifyPhrases(not_null<PeerData*> peer); [[nodiscard]] BotVerifyPhrases PeerVerifyPhrases(not_null<PeerData*> peer);

View file

@ -714,28 +714,30 @@ bool ChannelData::canRestrictParticipant(
return adminRights() & AdminRight::BanUsers; return adminRights() & AdminRight::BanUsers;
} }
void ChannelData::setVerifyDetails(Ui::VerifyDetails details) { void ChannelData::setBotVerifyDetails(Ui::BotVerifyDetails details) {
if (!details) { if (!details) {
if (_verifyDetails) { if (_botVerifyDetails) {
_verifyDetails = nullptr; _botVerifyDetails = nullptr;
session().changes().peerUpdated(this, UpdateFlag::VerifyInfo); session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
} }
} else if (!_verifyDetails) { } else if (!_botVerifyDetails) {
_verifyDetails = std::make_unique<Ui::VerifyDetails>(details); _botVerifyDetails = std::make_unique<Ui::BotVerifyDetails>(details);
session().changes().peerUpdated(this, UpdateFlag::VerifyInfo); session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
} else if (*_verifyDetails != details) { } else if (*_botVerifyDetails != details) {
*_verifyDetails = details; *_botVerifyDetails = details;
session().changes().peerUpdated(this, UpdateFlag::VerifyInfo); session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
} }
} }
void ChannelData::setVerifyDetailsIcon(DocumentId iconId) { void ChannelData::setBotVerifyDetailsIcon(DocumentId iconId) {
if (!iconId) { if (!iconId) {
setVerifyDetails({}); setBotVerifyDetails({});
} else { } else {
auto info = _verifyDetails ? *_verifyDetails : Ui::VerifyDetails(); auto info = _botVerifyDetails
info.iconBgId = iconId; ? *_botVerifyDetails
setVerifyDetails(info); : Ui::BotVerifyDetails();
info.iconId = iconId;
setBotVerifyDetails(info);
} }
} }
@ -1277,7 +1279,8 @@ void ApplyChannelUpdate(
.paidEnabled = update.is_paid_reactions_available(), .paidEnabled = update.is_paid_reactions_available(),
}); });
} }
channel->setVerifyDetails(ParseVerifyDetails(update.vbot_verification())); channel->setBotVerifyDetails(
ParseBotVerifyDetails(update.vbot_verification()));
channel->owner().stories().apply(channel, update.vstories()); channel->owner().stories().apply(channel, update.vstories());
channel->fullUpdated(); channel->fullUpdated();
channel->setPendingRequestsCount( channel->setPendingRequestsCount(

View file

@ -376,10 +376,10 @@ public:
[[nodiscard]] bool canRestrictParticipant( [[nodiscard]] bool canRestrictParticipant(
not_null<PeerData*> participant) const; not_null<PeerData*> participant) const;
void setVerifyDetails(Ui::VerifyDetails details); void setBotVerifyDetails(Ui::BotVerifyDetails details);
void setVerifyDetailsIcon(DocumentId iconId); void setBotVerifyDetailsIcon(DocumentId iconId);
[[nodiscard]] Ui::VerifyDetails *verifyDetails() const { [[nodiscard]] Ui::BotVerifyDetails *botVerifyDetails() const {
return _verifyDetails.get(); return _botVerifyDetails.get();
} }
void setInviteLink(const QString &newInviteLink); void setInviteLink(const QString &newInviteLink);
@ -552,7 +552,7 @@ private:
std::unique_ptr<Data::GroupCall> _call; std::unique_ptr<Data::GroupCall> _call;
PeerId _callDefaultJoinAs = 0; PeerId _callDefaultJoinAs = 0;
std::unique_ptr<Ui::VerifyDetails> _verifyDetails; std::unique_ptr<Ui::BotVerifyDetails> _botVerifyDetails;
}; };

View file

@ -1247,22 +1247,15 @@ void PeerData::setStoriesHidden(bool hidden) {
} }
} }
Ui::VerifyDetails *PeerData::verifyDetails() const { Ui::BotVerifyDetails *PeerData::botVerifyDetails() const {
if (const auto user = asUser()) { if (const auto user = asUser()) {
return user->verifyDetails(); return user->botVerifyDetails();
} else if (const auto channel = asChannel()) { } else if (const auto channel = asChannel()) {
return channel->verifyDetails(); return channel->botVerifyDetails();
} }
return nullptr; return nullptr;
} }
bool PeerData::verifiedByTelegram() const {
if (const auto details = verifyDetails()) {
return (details->iconBgId == owner().verifiedByTelegram().iconBgId);
}
return false;
}
Data::Forum *PeerData::forum() const { Data::Forum *PeerData::forum() const {
if (const auto channel = asChannel()) { if (const auto channel = asChannel()) {
return channel->forum(); return channel->forum();

View file

@ -23,7 +23,7 @@ enum class ChatRestriction;
namespace Ui { namespace Ui {
class EmptyUserpic; class EmptyUserpic;
struct VerifyDetails; struct BotVerifyDetails;
} // namespace Ui } // namespace Ui
namespace Main { namespace Main {
@ -234,8 +234,7 @@ public:
[[nodiscard]] bool hasStoriesHidden() const; [[nodiscard]] bool hasStoriesHidden() const;
void setStoriesHidden(bool hidden); void setStoriesHidden(bool hidden);
[[nodiscard]] Ui::VerifyDetails *verifyDetails() const; [[nodiscard]] Ui::BotVerifyDetails *botVerifyDetails() const;
[[nodiscard]] bool verifiedByTelegram() const;
[[nodiscard]] bool isNotificationsUser() const { [[nodiscard]] bool isNotificationsUser() const {
return (id == peerFromUser(333000)) return (id == peerFromUser(333000))

View file

@ -30,7 +30,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_media.h" #include "history/view/media/history_view_media.h"
#include "history/view/history_view_element.h" #include "history/view/history_view_element.h"
#include "inline_bots/inline_bot_layout_item.h" #include "inline_bots/inline_bot_layout_item.h"
#include "storage/localimageloader.h"
#include "storage/storage_account.h" #include "storage/storage_account.h"
#include "storage/storage_encrypted_file.h" #include "storage/storage_encrypted_file.h"
#include "media/player/media_player_instance.h" // instance()->play() #include "media/player/media_player_instance.h" // instance()->play()
@ -81,11 +80,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/random.h" #include "base/random.h"
#include "spellcheck/spellcheck_highlight_syntax.h" #include "spellcheck/spellcheck_highlight_syntax.h"
#include "ui/chat/attach/attach_prepare.h"
#include "ui/unread_badge.h"
#include "styles/style_dialogs.h"
#include <QtCore/QBuffer>
namespace Data { namespace Data {
namespace { namespace {
@ -336,26 +330,6 @@ Session::Session(not_null<Main::Session*> session)
}, _lifetime); }, _lifetime);
} }
Ui::VerifyDetails Session::verifiedByTelegram() {
if (!_verifiedByTelegramIconBgId) {
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 = bg->id;
_verifiedByTelegramIconFgId = fg->id;
}
return {
.iconBgId = _verifiedByTelegramIconBgId,
.iconFgId = _verifiedByTelegramIconFgId,
};
}
void Session::subscribeForTopicRepliesLists() { void Session::subscribeForTopicRepliesLists() {
repliesReadTillUpdates( repliesReadTillUpdates(
) | rpl::start_with_next([=](const RepliesReadTillUpdate &update) { ) | rpl::start_with_next([=](const RepliesReadTillUpdate &update) {
@ -596,11 +570,8 @@ not_null<UserData*> Session::processUser(const MTPUser &data) {
| (data.is_stories_hidden() ? Flag::StoriesHidden : Flag()) | (data.is_stories_hidden() ? Flag::StoriesHidden : Flag())
: Flag()); : Flag());
result->setFlags((result->flags() & ~flagsMask) | flagsSet); result->setFlags((result->flags() & ~flagsMask) | flagsSet);
if (data.is_verified()) { result->setBotVerifyDetailsIcon(
result->setVerifyDetails(verifiedByTelegram()); data.vbot_verification_icon().value_or_empty());
} else {
result->setVerifyDetailsIcon(data.vbot_verification_icon().value_or_empty());
}
if (minimal) { if (minimal) {
if (result->input.type() == mtpc_inputPeerEmpty) { if (result->input.type() == mtpc_inputPeerEmpty) {
result->input = MTP_inputPeerUser( result->input = MTP_inputPeerUser(
@ -1016,12 +987,8 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
? Flag::StoriesHidden ? Flag::StoriesHidden
: Flag()); : Flag());
channel->setFlags((channel->flags() & ~flagsMask) | flagsSet); channel->setFlags((channel->flags() & ~flagsMask) | flagsSet);
if (data.is_verified()) { channel->setBotVerifyDetailsIcon(
channel->setVerifyDetails(verifiedByTelegram()); data.vbot_verification_icon().value_or_empty());
} else {
channel->setVerifyDetailsIcon(
data.vbot_verification_icon().value_or_empty());
}
if (!minimal && storiesState) { if (!minimal && storiesState) {
result->setStoriesState(!storiesState->maxId result->setStoriesState(!storiesState->maxId
? UserData::StoriesState::None ? UserData::StoriesState::None

View file

@ -177,8 +177,6 @@ public:
return ++_nonHistoryEntryId; return ++_nonHistoryEntryId;
} }
[[nodiscard]] Ui::VerifyDetails verifiedByTelegram();
void subscribeForTopicRepliesLists(); void subscribeForTopicRepliesLists();
void clear(); void clear();
@ -1142,9 +1140,6 @@ private:
const std::unique_ptr<BusinessInfo> _businessInfo; const std::unique_ptr<BusinessInfo> _businessInfo;
std::unique_ptr<ShortcutMessages> _shortcutMessages; std::unique_ptr<ShortcutMessages> _shortcutMessages;
DocumentId _verifiedByTelegramIconBgId = 0;
DocumentId _verifiedByTelegramIconFgId = 0;
MsgId _nonHistoryEntryId = ShortcutMaxMsgId; MsgId _nonHistoryEntryId = ShortcutMaxMsgId;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;

View file

@ -556,28 +556,30 @@ bool UserData::isUsernameEditable(QString username) const {
return _username.isEditable(username); return _username.isEditable(username);
} }
void UserData::setVerifyDetails(Ui::VerifyDetails details) { void UserData::setBotVerifyDetails(Ui::BotVerifyDetails details) {
if (!details) { if (!details) {
if (_verifyDetails) { if (_botVerifyDetails) {
_verifyDetails = nullptr; _botVerifyDetails = nullptr;
session().changes().peerUpdated(this, UpdateFlag::VerifyInfo); session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
} }
} else if (!_verifyDetails) { } else if (!_botVerifyDetails) {
_verifyDetails = std::make_unique<Ui::VerifyDetails>(details); _botVerifyDetails = std::make_unique<Ui::BotVerifyDetails>(details);
session().changes().peerUpdated(this, UpdateFlag::VerifyInfo); session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
} else if (*_verifyDetails != details) { } else if (*_botVerifyDetails != details) {
*_verifyDetails = details; *_botVerifyDetails = details;
session().changes().peerUpdated(this, UpdateFlag::VerifyInfo); session().changes().peerUpdated(this, UpdateFlag::VerifyInfo);
} }
} }
void UserData::setVerifyDetailsIcon(DocumentId iconId) { void UserData::setBotVerifyDetailsIcon(DocumentId iconId) {
if (!iconId) { if (!iconId) {
setVerifyDetails({}); setBotVerifyDetails({});
} else { } else {
auto info = _verifyDetails ? *_verifyDetails : Ui::VerifyDetails(); auto info = _botVerifyDetails
info.iconBgId = iconId; ? *_botVerifyDetails
setVerifyDetails(info); : Ui::BotVerifyDetails();
info.iconId = iconId;
setBotVerifyDetails(info);
} }
} }
@ -792,7 +794,8 @@ void ApplyUserUpdate(not_null<UserData*> user, const MTPDuserFull &update) {
user->owner().businessInfo().applyGreetingSettings( user->owner().businessInfo().applyGreetingSettings(
FromMTP(&user->owner(), update.vbusiness_greeting_message())); FromMTP(&user->owner(), update.vbusiness_greeting_message()));
} }
user->setVerifyDetails(ParseVerifyDetails(update.vbot_verification())); user->setBotVerifyDetails(
ParseBotVerifyDetails(update.vbot_verification()));
user->owner().stories().apply(user, update.vstories()); user->owner().stories().apply(user, update.vstories());
@ -814,7 +817,7 @@ StarRefProgram ParseStarRefProgram(const MTPStarRefProgram *program) {
return result; return result;
} }
Ui::VerifyDetails ParseVerifyDetails(const MTPBotVerification *info) { Ui::BotVerifyDetails ParseBotVerifyDetails(const MTPBotVerification *info) {
if (!info) { if (!info) {
return {}; return {};
} }
@ -823,7 +826,7 @@ Ui::VerifyDetails ParseVerifyDetails(const MTPBotVerification *info) {
const auto flags = TextParseLinks; const auto flags = TextParseLinks;
return { return {
.botId = UserId(data.vbot_id().v), .botId = UserId(data.vbot_id().v),
.iconBgId = DocumentId(data.vicon().v), .iconId = DocumentId(data.vicon().v),
.description = TextUtilities::ParseEntities(description, flags), .description = TextUtilities::ParseEntities(description, flags),
}; };
} }

View file

@ -193,10 +193,10 @@ public:
[[nodiscard]] const std::vector<QString> &usernames() const; [[nodiscard]] const std::vector<QString> &usernames() const;
[[nodiscard]] bool isUsernameEditable(QString username) const; [[nodiscard]] bool isUsernameEditable(QString username) const;
void setVerifyDetails(Ui::VerifyDetails details); void setBotVerifyDetails(Ui::BotVerifyDetails details);
void setVerifyDetailsIcon(DocumentId iconId); void setBotVerifyDetailsIcon(DocumentId iconId);
[[nodiscard]] Ui::VerifyDetails *verifyDetails() const { [[nodiscard]] Ui::BotVerifyDetails *botVerifyDetails() const {
return _verifyDetails.get(); return _botVerifyDetails.get();
} }
enum class ContactStatus : char { enum class ContactStatus : char {
@ -277,7 +277,7 @@ private:
std::vector<Data::UnavailableReason> _unavailableReasons; std::vector<Data::UnavailableReason> _unavailableReasons;
QString _phone; QString _phone;
QString _privateForwardName; QString _privateForwardName;
std::unique_ptr<Ui::VerifyDetails> _verifyDetails; std::unique_ptr<Ui::BotVerifyDetails> _botVerifyDetails;
ChannelId _personalChannelId = 0; ChannelId _personalChannelId = 0;
MsgId _personalChannelMessageId = 0; MsgId _personalChannelMessageId = 0;
@ -295,7 +295,7 @@ void ApplyUserUpdate(not_null<UserData*> user, const MTPDuserFull &update);
[[nodiscard]] StarRefProgram ParseStarRefProgram( [[nodiscard]] StarRefProgram ParseStarRefProgram(
const MTPStarRefProgram *program); const MTPStarRefProgram *program);
[[nodiscard]] Ui::VerifyDetails ParseVerifyDetails( [[nodiscard]] Ui::BotVerifyDetails ParseBotVerifyDetails(
const MTPBotVerification *info); const MTPBotVerification *info);
} // namespace Data } // namespace Data

View file

@ -32,8 +32,7 @@ ThreeStateIcon {
} }
VerifiedBadge { VerifiedBadge {
bg: color; color: color;
fg: color;
height: pixels; height: pixels;
} }
@ -411,18 +410,27 @@ dialogsLockIcon: ThreeStateIcon {
dialogsVerifiedColors: VerifiedBadge { dialogsVerifiedColors: VerifiedBadge {
height: 20px; height: 20px;
bg: dialogsVerifiedIconBg; color: dialogsVerifiedIconBg;
fg: dialogsVerifiedIconFg;
} }
dialogsVerifiedColorsOver: VerifiedBadge(dialogsVerifiedColors) { dialogsVerifiedColorsOver: VerifiedBadge(dialogsVerifiedColors) {
bg: dialogsVerifiedIconBgOver; color: dialogsVerifiedIconBgOver;
fg: dialogsVerifiedIconFgOver;
} }
dialogsVerifiedColorsActive: VerifiedBadge(dialogsVerifiedColors) { dialogsVerifiedColorsActive: VerifiedBadge(dialogsVerifiedColors) {
bg: dialogsVerifiedIconBgActive; color: dialogsVerifiedIconBgActive;
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

@ -1385,10 +1385,10 @@ void InnerWidget::paintPeerSearchResult(
Ui::NameTextOptions()); Ui::NameTextOptions());
} }
if (const auto details = peer->verifyDetails()) { if (const auto info = peer->botVerifyDetails()) {
if (!result->badge.ready(details)) { if (!result->badge.ready(info)) {
result->badge.set( result->badge.set(
details, info,
peer->owner().customEmojiManager().factory(), peer->owner().customEmojiManager().factory(),
[=] { updateSearchResult(peer); }); [=] { updateSearchResult(peer); });
} }
@ -1409,6 +1409,11 @@ 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

@ -449,10 +449,10 @@ void PaintRow(
? tr::lng_badge_psa_default(tr::now) ? tr::lng_badge_psa_default(tr::now)
: custom; : custom;
PaintRowTopRight(p, text, rectForName, context); PaintRowTopRight(p, text, rectForName, context);
} else if (const auto details = from ? from->verifyDetails() : nullptr) { } else if (const auto info = from ? from->botVerifyDetails() : nullptr) {
if (!rowBadge.ready(details)) { if (!rowBadge.ready(info)) {
rowBadge.set( rowBadge.set(
details, info,
from->owner().customEmojiManager().factory(), from->owner().customEmojiManager().factory(),
customEmojiRepaint); customEmojiRepaint);
} }
@ -739,6 +739,11 @@ 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

@ -566,10 +566,10 @@ void TopBarWidget::paintTopBar(Painter &p) {
TopBarNameText(namePeer, _activeChat.section), TopBarNameText(namePeer, _activeChat.section),
Ui::NameTextOptions()); Ui::NameTextOptions());
} }
if (const auto details = namePeer->verifyDetails()) { if (const auto info = namePeer->botVerifyDetails()) {
if (!_titleBadge.ready(details)) { if (!_titleBadge.ready(info)) {
_titleBadge.set( _titleBadge.set(
details, info,
namePeer->owner().customEmojiManager().factory(), namePeer->owner().customEmojiManager().factory(),
[=] { update(); }); [=] { update(); });
} }
@ -589,6 +589,7 @@ 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,9 +22,9 @@ InfoToggle {
} }
InfoPeerBadge { InfoPeerBadge {
verified: icon;
premium: icon; premium: icon;
premiumFg: color; premiumFg: color;
premiumInnerFg: color;
position: point; position: point;
sizeTag: int; sizeTag: int;
} }
@ -436,9 +436,9 @@ 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;
position: infoVerifiedCheckPosition; position: infoVerifiedCheckPosition;
sizeTag: 1; // Large sizeTag: 1; // Large
} }

View file

@ -1845,7 +1845,7 @@ void DetailsFiller::setupAboutVerification() {
peer, peer,
Data::PeerUpdate::Flag::VerifyInfo Data::PeerUpdate::Flag::VerifyInfo
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
const auto info = peer->verifyDetails(); const auto info = peer->botVerifyDetails();
while (inner->count()) { while (inner->count()) {
delete inner->widgetAt(0); delete inner->widgetAt(0);
} }
@ -1853,9 +1853,6 @@ void DetailsFiller::setupAboutVerification() {
Ui::AddDivider(inner); Ui::AddDivider(inner);
} else if (!info->description.empty()) { } else if (!info->description.empty()) {
Ui::AddDividerText(inner, rpl::single(info->description)); Ui::AddDividerText(inner, rpl::single(info->description));
} else if (peer->verifiedByTelegram()) {
const auto phrases = PeerVerifyPhrases(peer);
Ui::AddDividerText(inner, phrases.telegram());
} }
inner->resizeToWidth(inner->width()); inner->resizeToWidth(inner->width());
}, inner->lifetime()); }, inner->lifetime());

View file

@ -35,10 +35,7 @@ namespace {
} else if (emojiStatusId && badge == BadgeType::None) { } else if (emojiStatusId && badge == BadgeType::None) {
badge = BadgeType::Premium; badge = BadgeType::Premium;
} }
return Badge::Content{ return Badge::Content{ badge, emojiStatusId };
badge,
emojiStatusId ? emojiStatusId : DocumentId(),
};
}); });
} }
@ -117,30 +114,16 @@ void Badge::setContent(Content content) {
case BadgeType::Verified: case BadgeType::Verified:
case BadgeType::Premium: { case BadgeType::Premium: {
const auto id = _content.emojiStatusId; const auto id = _content.emojiStatusId;
const auto innerId = _content.emojiStatusInnerId; if (id) {
if (id || innerId) { _emojiStatus = _session->data().customEmojiManager().create(
_emojiStatus = id id,
? _session->data().customEmojiManager().create( [raw = _view.data()] { raw->update(); },
id, sizeTag());
[raw = _view.data()] { raw->update(); }, if (_customStatusLoopsLimit > 0) {
sizeTag())
: nullptr;
_statusInner = innerId
? _session->data().customEmojiManager().create(
innerId,
[raw = _view.data()] { raw->update(); },
sizeTag())
: nullptr;
if (_emojiStatus && _customStatusLoopsLimit > 0) {
_emojiStatus = std::make_unique<Ui::Text::LimitedLoopsEmoji>( _emojiStatus = std::make_unique<Ui::Text::LimitedLoopsEmoji>(
std::move(_emojiStatus), std::move(_emojiStatus),
_customStatusLoopsLimit); _customStatusLoopsLimit);
} }
if (_statusInner && _customStatusLoopsLimit > 0) {
_statusInner = std::make_unique<Ui::Text::LimitedLoopsEmoji>(
std::move(_statusInner),
_customStatusLoopsLimit);
}
const auto emoji = Data::FrameSizeFromTag(sizeTag()) const auto emoji = Data::FrameSizeFromTag(sizeTag())
/ style::DevicePixelRatio(); / style::DevicePixelRatio();
_view->resize(emoji, emoji); _view->resize(emoji, emoji);
@ -155,17 +138,13 @@ void Badge::setContent(Content content) {
if (!_emojiStatusPanel if (!_emojiStatusPanel
|| !_emojiStatusPanel->paintBadgeFrame(check)) { || !_emojiStatusPanel->paintBadgeFrame(check)) {
Painter p(check); Painter p(check);
if (_emojiStatus) { _emojiStatus->paint(p, args);
_emojiStatus->paint(p, args);
}
if (_statusInner) {
args.textColor = _st.premiumInnerFg->c;
_statusInner->paint(p, args);
}
} }
}, _view->lifetime()); }, _view->lifetime());
} else { } else {
const auto icon = &_st.premium; const auto icon = (_content.badge == BadgeType::Verified)
? &_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()]{
@ -225,9 +204,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
const auto fake = (!_emojiStatus && !star) || _content.badge == BadgeType::Verified);
|| (_content.badge == BadgeType::Verified); const auto fake = !_emojiStatus && !star;
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

@ -59,7 +59,6 @@ public:
struct Content { struct Content {
BadgeType badge = BadgeType::None; BadgeType badge = BadgeType::None;
DocumentId emojiStatusId = 0; DocumentId emojiStatusId = 0;
DocumentId emojiStatusInnerId = 0;
friend inline constexpr bool operator==(Content, Content) = default; friend inline constexpr bool operator==(Content, Content) = default;
}; };
@ -93,7 +92,6 @@ private:
EmojiStatusPanel *_emojiStatusPanel = nullptr; EmojiStatusPanel *_emojiStatusPanel = nullptr;
const int _customStatusLoopsLimit = 0; const int _customStatusLoopsLimit = 0;
std::unique_ptr<Ui::Text::CustomEmoji> _emojiStatus; std::unique_ptr<Ui::Text::CustomEmoji> _emojiStatus;
std::unique_ptr<Ui::Text::CustomEmoji> _statusInner;
base::flags<BadgeType> _allowed; base::flags<BadgeType> _allowed;
Content _content; Content _content;
Fn<void()> _premiumClickCallback; Fn<void()> _premiumClickCallback;

View file

@ -309,11 +309,10 @@ Cover::Cover(
peer, peer,
Data::PeerUpdate::Flag::VerifyInfo Data::PeerUpdate::Flag::VerifyInfo
) | rpl::map([=] { ) | rpl::map([=] {
const auto details = peer->verifyDetails(); const auto info = peer->botVerifyDetails();
return Badge::Content{ return Badge::Content{
.badge = details ? BadgeType::Verified : BadgeType::None, .badge = info ? BadgeType::Verified : BadgeType::None,
.emojiStatusId = details ? details->iconBgId : DocumentId(), .emojiStatusId = info ? info->iconId : DocumentId(),
.emojiStatusInnerId = details ? details->iconFgId : DocumentId(),
}; };
}); });
} }

View file

@ -659,6 +659,8 @@ rpl::producer<BadgeType> BadgeValueFromFlags(Peer peer) {
? BadgeType::Scam ? BadgeType::Scam
: (value & Flag::Fake) : (value & Flag::Fake)
? BadgeType::Fake ? BadgeType::Fake
: (value & Flag::Verified)
? BadgeType::Verified
: premium : premium
? BadgeType::Premium ? BadgeType::Premium
: BadgeType::None; : BadgeType::None;

View file

@ -197,9 +197,12 @@ 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;
sizeTag: 0; // Normal sizeTag: 0; // Normal
} }

View file

@ -31,11 +31,9 @@ struct PeerBadge::EmojiStatus {
int skip = 0; int skip = 0;
}; };
struct PeerBadge::VerifiedData { struct PeerBadge::BotVerifiedData {
QImage cache; QImage cache;
QImage cacheFg; std::unique_ptr<Text::CustomEmoji> icon;
std::unique_ptr<Text::CustomEmoji> bg;
std::unique_ptr<Text::CustomEmoji> fg;
}; };
void UnreadBadge::setText(const QString &text, bool active) { void UnreadBadge::setText(const QString &text, bool active) {
@ -200,6 +198,14 @@ int PeerBadge::drawGetWidth(
.paused = descriptor.paused || On(PowerSaving::kEmojiStatus), .paused = descriptor.paused || On(PowerSaving::kEmojiStatus),
}); });
return iconw - 4 * _emojiStatus->skip; return iconw - 4 * _emojiStatus->skip;
} else if (descriptor.verified && peer->isVerified()) {
const auto iconw = descriptor.verified->width();
descriptor.verified->paint(
p,
rectForName.x() + qMin(nameWidth, rectForName.width() - iconw),
rectForName.y(),
outerWidth);
return iconw;
} else if (descriptor.premium } else if (descriptor.premium
&& peer->isPremium() && peer->isPremium()
&& peer->session().premiumBadgesShown()) { && peer->session().premiumBadgesShown()) {
@ -218,45 +224,33 @@ void PeerBadge::unload() {
_emojiStatus = nullptr; _emojiStatus = nullptr;
} }
bool PeerBadge::ready(const VerifyDetails *details) const { bool PeerBadge::ready(const BotVerifyDetails *details) const {
if (!details || !*details) { if (!details || !*details) {
_verifiedData = nullptr; _botVerifiedData = nullptr;
return true; return true;
} else if (!_verifiedData) { } else if (!_botVerifiedData) {
return false; return false;
} }
if (!details->iconBgId) { if (!details->iconId) {
_verifiedData->bg = nullptr; _botVerifiedData->icon = nullptr;
} else if (!_verifiedData->bg } else if (!_botVerifiedData->icon
|| (_verifiedData->bg->entityData() || (_botVerifiedData->icon->entityData()
!= Data::SerializeCustomEmojiId(details->iconBgId))) { != Data::SerializeCustomEmojiId(details->iconId))) {
return false;
}
if (!details->iconFgId) {
_verifiedData->fg = nullptr;
} else if (!_verifiedData->fg
|| (_verifiedData->fg->entityData()
!= Data::SerializeCustomEmojiId(details->iconFgId))) {
return false; return false;
} }
return true; return true;
} }
void PeerBadge::set( void PeerBadge::set(
not_null<const VerifyDetails*> details, not_null<const BotVerifyDetails*> details,
Ui::Text::CustomEmojiFactory factory, Ui::Text::CustomEmojiFactory factory,
Fn<void()> repaint) { Fn<void()> repaint) {
if (!_verifiedData) { if (!_botVerifiedData) {
_verifiedData = std::make_unique<VerifiedData>(); _botVerifiedData = std::make_unique<BotVerifiedData>();
} }
if (details->iconBgId) { if (details->iconId) {
_verifiedData->bg = factory( _botVerifiedData->icon = factory(
Data::SerializeCustomEmojiId(details->iconBgId), Data::SerializeCustomEmojiId(details->iconId),
repaint);
}
if (details->iconFgId) {
_verifiedData->fg = factory(
Data::SerializeCustomEmojiId(details->iconFgId),
repaint); repaint);
} }
} }
@ -265,29 +259,19 @@ int PeerBadge::drawVerified(
QPainter &p, QPainter &p,
QPoint position, QPoint position,
const style::VerifiedBadge &st) { const style::VerifiedBadge &st) {
const auto data = _verifiedData.get(); const auto data = _botVerifiedData.get();
if (!data) { if (!data) {
return 0; return 0;
} }
const auto now = crl::now(); if (const auto icon = data->icon.get()) {
auto result = 0; icon->paint(p, {
if (const auto bg = data->bg.get()) { .textColor = st.color->c,
bg->paint(p, { .now = crl::now(),
.textColor = st.bg->c,
.now = now,
.position = position, .position = position,
}); });
result = bg->width(); return icon->width();
} }
if (const auto fg = data->fg.get()) { return 0;
fg->paint(p, {
.textColor = st.fg->c,
.now = now,
.position = position,
});
result = std::max(result, fg->width());
}
return result;
} }
} // namespace Ui } // namespace Ui

View file

@ -32,18 +32,17 @@ private:
}; };
struct VerifyDetails { struct BotVerifyDetails {
UserId botId = 0; UserId botId = 0;
DocumentId iconBgId = 0; DocumentId iconId = 0;
DocumentId iconFgId = 0;
TextWithEntities description; TextWithEntities description;
explicit operator bool() const { explicit operator bool() const {
return iconBgId || iconFgId; return iconId != 0;
} }
friend inline bool operator==( friend inline bool operator==(
const VerifyDetails &, const BotVerifyDetails &,
const VerifyDetails &) = default; const BotVerifyDetails &) = default;
}; };
class PeerBadge { class PeerBadge {
@ -69,9 +68,9 @@ public:
const Descriptor &descriptor); const Descriptor &descriptor);
void unload(); void unload();
[[nodiscard]] bool ready(const VerifyDetails *details) const; [[nodiscard]] bool ready(const BotVerifyDetails *details) const;
void set( void set(
not_null<const VerifyDetails*> details, not_null<const BotVerifyDetails*> details,
Text::CustomEmojiFactory factory, Text::CustomEmojiFactory factory,
Fn<void()> repaint); Fn<void()> repaint);
@ -83,10 +82,10 @@ public:
private: private:
struct EmojiStatus; struct EmojiStatus;
struct VerifiedData; struct BotVerifiedData;
std::unique_ptr<EmojiStatus> _emojiStatus; std::unique_ptr<EmojiStatus> _emojiStatus;
mutable std::unique_ptr<VerifiedData> _verifiedData; mutable std::unique_ptr<BotVerifiedData> _botVerifiedData;
}; };