From 4b6107fa56883cd57653648b0ecacbb959dd85b6 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 16 Oct 2023 13:52:08 +0400 Subject: [PATCH] Use color index from API. --- Telegram/SourceFiles/calls/calls_userpic.cpp | 3 +- Telegram/SourceFiles/data/data_changes.h | 55 +++++------ Telegram/SourceFiles/data/data_peer.cpp | 35 ++++++- Telegram/SourceFiles/data/data_peer.h | 32 +++---- Telegram/SourceFiles/data/data_session.cpp | 6 ++ .../export/data/export_data_types.cpp | 34 ++++--- .../export/data/export_data_types.h | 13 ++- .../export/output/export_output_html.cpp | 8 +- .../export/output/export_output_html.h | 2 +- .../history/history_item_components.cpp | 28 +++--- .../history/history_item_components.h | 9 +- .../history/view/history_view_message.cpp | 33 +------ .../history/view/history_view_message.h | 2 +- .../view/media/history_view_contact.cpp | 2 +- .../view/media/history_view_document.cpp | 2 +- .../media/history_view_extended_preview.cpp | 2 +- .../history/view/media/history_view_gif.cpp | 2 +- .../view/media/history_view_media_grouped.cpp | 2 +- .../history/view/media/history_view_photo.cpp | 2 +- .../inline_bots/inline_bot_layout_item.cpp | 3 +- Telegram/SourceFiles/ui/chat/chat_style.cpp | 92 +++++++++++++++++-- Telegram/SourceFiles/ui/chat/chat_style.h | 41 ++++++++- .../ui/controls/userpic_button.cpp | 3 +- Telegram/SourceFiles/ui/empty_userpic.cpp | 13 ++- Telegram/SourceFiles/ui/empty_userpic.h | 5 +- .../window/themes/window_theme_preview.cpp | 2 +- 26 files changed, 282 insertions(+), 149 deletions(-) diff --git a/Telegram/SourceFiles/calls/calls_userpic.cpp b/Telegram/SourceFiles/calls/calls_userpic.cpp index f296ef0c6..38f467170 100644 --- a/Telegram/SourceFiles/calls/calls_userpic.cpp +++ b/Telegram/SourceFiles/calls/calls_userpic.cpp @@ -202,8 +202,7 @@ void Userpic::createCache(Image *image) { { auto p = QPainter(&filled); Ui::EmptyUserpic( - Ui::EmptyUserpic::UserpicColor( - Data::PeerColorIndex(_peer->id)), + Ui::EmptyUserpic::UserpicColor(_peer->colorIndex()), _peer->name() ).paintCircle(p, 0, 0, size, size); } diff --git a/Telegram/SourceFiles/data/data_changes.h b/Telegram/SourceFiles/data/data_changes.h index 12cfa7353..a7f52b98b 100644 --- a/Telegram/SourceFiles/data/data_changes.h +++ b/Telegram/SourceFiles/data/data_changes.h @@ -71,41 +71,42 @@ struct PeerUpdate { FullInfo = (1ULL << 11), Usernames = (1ULL << 12), TranslationDisabled = (1ULL << 13), + Color = (1ULL << 14), // For users - CanShareContact = (1ULL << 14), - IsContact = (1ULL << 15), - PhoneNumber = (1ULL << 16), - OnlineStatus = (1ULL << 17), - BotCommands = (1ULL << 18), - BotCanBeInvited = (1ULL << 19), - BotStartToken = (1ULL << 20), - CommonChats = (1ULL << 21), - HasCalls = (1ULL << 22), - SupportInfo = (1ULL << 23), - IsBot = (1ULL << 24), - EmojiStatus = (1ULL << 25), - StoriesState = (1ULL << 26), + CanShareContact = (1ULL << 15), + IsContact = (1ULL << 16), + PhoneNumber = (1ULL << 17), + OnlineStatus = (1ULL << 18), + BotCommands = (1ULL << 19), + BotCanBeInvited = (1ULL << 20), + BotStartToken = (1ULL << 21), + CommonChats = (1ULL << 22), + HasCalls = (1ULL << 23), + SupportInfo = (1ULL << 24), + IsBot = (1ULL << 25), + EmojiStatus = (1ULL << 26), + StoriesState = (1ULL << 27), // For chats and channels - InviteLinks = (1ULL << 27), - Members = (1ULL << 28), - Admins = (1ULL << 29), - BannedUsers = (1ULL << 30), - Rights = (1ULL << 31), - PendingRequests = (1ULL << 32), - Reactions = (1ULL << 33), + InviteLinks = (1ULL << 28), + Members = (1ULL << 29), + Admins = (1ULL << 30), + BannedUsers = (1ULL << 31), + Rights = (1ULL << 32), + PendingRequests = (1ULL << 33), + Reactions = (1ULL << 34), // For channels - ChannelAmIn = (1ULL << 34), - StickersSet = (1ULL << 35), - ChannelLinkedChat = (1ULL << 36), - ChannelLocation = (1ULL << 37), - Slowmode = (1ULL << 38), - GroupCall = (1ULL << 39), + ChannelAmIn = (1ULL << 35), + StickersSet = (1ULL << 36), + ChannelLinkedChat = (1ULL << 37), + ChannelLocation = (1ULL << 38), + Slowmode = (1ULL << 39), + GroupCall = (1ULL << 40), // For iteration - LastUsedBit = (1ULL << 39), + LastUsedBit = (1ULL << 40), }; using Flags = base::flags; friend inline constexpr auto is_flag_type(Flag) { return true; } diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 00c183161..76652a672 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -59,8 +59,8 @@ using UpdateFlag = Data::PeerUpdate::Flag; namespace Data { -int PeerColorIndex(PeerId peerId) { - return Ui::EmptyUserpic::ColorIndex(peerId.value & PeerId::kChatTypeMask); +uint8 DecideColorIndex(PeerId peerId) { + return Ui::DecideColorIndex(peerId.value & PeerId::kChatTypeMask); } PeerId FakePeerIdForJustName(const QString &name) { @@ -230,7 +230,7 @@ not_null PeerData::ensureEmptyUserpic() const { if (!_userpicEmpty) { const auto user = asUser(); _userpicEmpty = std::make_unique( - Ui::EmptyUserpic::UserpicColor(Data::PeerColorIndex(id)), + Ui::EmptyUserpic::UserpicColor(colorIndex()), ((user && user->isInaccessible()) ? Ui::EmptyUserpic::InaccessibleName() : name())); @@ -251,7 +251,7 @@ void PeerData::setUserpic( const ImageLocation &location, bool hasVideo) { _userpicPhotoId = photoId; - _userpicHasVideo = hasVideo; + _userpicHasVideo = hasVideo ? 1 : 0; _userpic.set(&session(), ImageWithLocation{ .location = location }); } @@ -389,6 +389,22 @@ QImage PeerData::generateUserpicImage( return result; } +ImageLocation PeerData::userpicLocation() const { + return _userpic.location(); +} + +bool PeerData::userpicPhotoUnknown() const { + return (_userpicPhotoId == kUnknownPhotoId); +} + +PhotoId PeerData::userpicPhotoId() const { + return userpicPhotoUnknown() ? 0 : _userpicPhotoId; +} + +bool PeerData::userpicHasVideo() const { + return _userpicHasVideo != 0; +} + Data::FileOrigin PeerData::userpicOrigin() const { return Data::FileOriginPeerPhoto(id); } @@ -428,7 +444,7 @@ void PeerData::setUserpicChecked( bool hasVideo) { if (_userpicPhotoId != photoId || _userpic.location() != location - || _userpicHasVideo != hasVideo) { + || _userpicHasVideo != (hasVideo ? 1 : 0)) { const auto known = !userpicPhotoUnknown(); setUserpic(photoId, location, hasVideo); session().changes().peerUpdated(this, UpdateFlag::Photo); @@ -818,6 +834,15 @@ QString PeerData::userName() const { return QString(); } +bool PeerData::changeColorIndex(uint8 index) { + index %= Ui::kColorIndexCount; + if (_colorIndex == index) { + return false; + } + _colorIndex = index; + return true; +} + bool PeerData::isSelf() const { if (const auto user = asUser()) { return (user->flags() & UserDataFlag::Self); diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index 73c3d85f8..b793ff381 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -39,7 +39,7 @@ class GroupCall; struct ReactionId; class WallPaper; -[[nodiscard]] int PeerColorIndex(PeerId peerId); +[[nodiscard]] uint8 DecideColorIndex(PeerId peerId); // Must be used only for PeerColor-s. [[nodiscard]] PeerId FakePeerIdForJustName(const QString &name); @@ -164,6 +164,11 @@ public: [[nodiscard]] Main::Session &session() const; [[nodiscard]] Main::Account &account() const; + [[nodiscard]] uint8 colorIndex() const { + return _colorIndex; + } + bool changeColorIndex(uint8 index); + [[nodiscard]] bool isUser() const { return peerIsUser(id); } @@ -285,20 +290,12 @@ public: Ui::PeerUserpicView &view, int size, std::optional radius = {}) const; - [[nodiscard]] ImageLocation userpicLocation() const { - return _userpic.location(); - } + [[nodiscard]] ImageLocation userpicLocation() const; static constexpr auto kUnknownPhotoId = PhotoId(0xFFFFFFFFFFFFFFFFULL); - [[nodiscard]] bool userpicPhotoUnknown() const { - return (_userpicPhotoId == kUnknownPhotoId); - } - [[nodiscard]] PhotoId userpicPhotoId() const { - return userpicPhotoUnknown() ? 0 : _userpicPhotoId; - } - [[nodiscard]] bool userpicHasVideo() const { - return _userpicHasVideo; - } + [[nodiscard]] bool userpicPhotoUnknown() const; + [[nodiscard]] PhotoId userpicPhotoId() const; + [[nodiscard]] bool userpicHasVideo() const; [[nodiscard]] Data::FileOrigin userpicOrigin() const; [[nodiscard]] Data::FileOrigin userpicPhotoOrigin() const; @@ -460,14 +457,15 @@ private: TimeId _ttlPeriod = 0; + QString _requestChatTitle; + TimeId _requestChatDate = 0; + Settings _settings = PeerSettings(PeerSetting::Unknown); BlockStatus _blockStatus = BlockStatus::Unknown; LoadedStatus _loadedStatus = LoadedStatus::Not; TranslationFlag _translationFlag = TranslationFlag::Unknown; - bool _userpicHasVideo = false; - - QString _requestChatTitle; - TimeId _requestChatDate = 0; + uint8 _colorIndex : 7 = 0; + uint8 _userpicHasVideo : 1 = 0; QString _about; QString _themeEmoticon; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 6039dcf21..26c019671 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -705,6 +705,9 @@ not_null Session::processUser(const MTPUser &data) { if (canShareThisContact != result->canShareThisContactFast()) { flags |= UpdateFlag::CanShareContact; } + if (result->changeColorIndex(uint8(data.vcolor().v))) { + flags |= UpdateFlag::Color; + } }); if (minimal) { @@ -979,6 +982,9 @@ not_null Session::processChat(const MTPChat &data) { if (wasCallNotEmpty != Data::ChannelHasActiveCall(channel)) { flags |= UpdateFlag::GroupCall; } + if (result->changeColorIndex(uint8(data.vcolor().v))) { + flags |= UpdateFlag::Color; + } }, [&](const MTPDchannelForbidden &data) { const auto channel = result->asChannel(); diff --git a/Telegram/SourceFiles/export/data/export_data_types.cpp b/Telegram/SourceFiles/export/data/export_data_types.cpp index ab6cb3e50..a0d07ba97 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.cpp +++ b/Telegram/SourceFiles/export/data/export_data_types.cpp @@ -54,17 +54,16 @@ QString PrepareStoryFileName( } // namespace -int PeerColorIndex(BareId bareId) { - const auto index = bareId % 7; - const int map[] = { 0, 7, 4, 1, 6, 3, 5 }; - return map[index]; +uint8 PeerColorIndex(BareId bareId) { + const uint8 map[] = { 0, 7, 4, 1, 6, 3, 5 }; + return map[bareId % base::array_size(map)]; } BareId PeerToBareId(PeerId peerId) { return (peerId.value & PeerId::kChatTypeMask); } -int PeerColorIndex(PeerId peerId) { +uint8 PeerColorIndex(PeerId peerId) { return PeerColorIndex(PeerToBareId(peerId)); } @@ -78,7 +77,7 @@ BareId StringBarePeerId(const Utf8String &data) { return result; } -int ApplicationColorIndex(int applicationId) { +uint8 ApplicationColorIndex(int applicationId) { static const auto official = std::map { { 1, 0 }, // iOS { 7, 0 }, // iOS X @@ -767,6 +766,7 @@ ContactInfo ParseContactInfo(const MTPUser &data) { auto result = ContactInfo(); data.match([&](const MTPDuser &data) { result.userId = data.vid().v; + result.colorIndex = data.vcolor().v; if (const auto firstName = data.vfirst_name()) { result.firstName = ParseString(*firstName); } @@ -778,15 +778,13 @@ ContactInfo ParseContactInfo(const MTPUser &data) { } }, [&](const MTPDuserEmpty &data) { result.userId = data.vid().v; + result.colorIndex = PeerColorIndex(result.userId); }); return result; } -int ContactColorIndex(const ContactInfo &data) { - if (data.userId != 0) { - return PeerColorIndex(data.userId.bare); - } - return PeerColorIndex(StringBarePeerId(data.phoneNumber)); +uint8 ContactColorIndex(const ContactInfo &data) { + return data.colorIndex; } PeerId User::id() const { @@ -798,6 +796,7 @@ User ParseUser(const MTPUser &data) { result.info = ParseContactInfo(data); data.match([&](const MTPDuser &data) { result.bareId = data.vid().v; + result.colorIndex = data.vcolor().v; if (const auto username = data.vusername()) { result.username = ParseString(*username); } @@ -852,6 +851,7 @@ Chat ParseChat(const MTPChat &data) { result.input = MTP_inputPeerChat(MTP_long(result.bareId)); }, [&](const MTPDchannel &data) { result.bareId = data.vid().v; + result.colorIndex = data.vcolor().v; result.isBroadcast = data.is_broadcast(); result.isSupergroup = data.is_megagroup(); result.title = ParseString(data.vtitle()); @@ -935,6 +935,15 @@ MTPInputPeer Peer::input() const { Unexpected("Variant in Peer::id."); } +uint8 Peer::colorIndex() const { + if (const auto user = this->user()) { + return user->colorIndex; + } else if (const auto chat = this->chat()) { + return chat->colorIndex; + } + Unexpected("Variant in Peer::colorIndex."); +} + std::map ParsePeersLists( const MTPVector &users, const MTPVector &chats) { @@ -1541,6 +1550,8 @@ ContactsList ParseContactsList(const MTPVector &data) { info.lastName = ParseString(data.vlast_name()); info.phoneNumber = ParseString(data.vphone()); info.date = data.vdate().v; + info.colorIndex = PeerColorIndex( + StringBarePeerId(info.phoneNumber)); return info; }); result.list.push_back(std::move(info)); @@ -1758,6 +1769,7 @@ DialogsInfo ParseDialogsInfo(const MTPmessages_Dialogs &data) { info.lastName = peer.user() ? peer.user()->info.lastName : Utf8String(); + info.colorIndex = peer.colorIndex(); info.input = peer.input(); info.migratedToChannelId = peer.chat() ? peer.chat()->migratedToChannelId diff --git a/Telegram/SourceFiles/export/data/export_data_types.h b/Telegram/SourceFiles/export/data/export_data_types.h index 6556a35b3..e670c9a5c 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.h +++ b/Telegram/SourceFiles/export/data/export_data_types.h @@ -24,10 +24,10 @@ namespace Data { using Utf8String = QByteArray; -int PeerColorIndex(BareId bareId); +uint8 PeerColorIndex(BareId bareId); BareId PeerToBareId(PeerId peerId); -int PeerColorIndex(PeerId peerId); -int ApplicationColorIndex(int applicationId); +uint8 PeerColorIndex(PeerId peerId); +uint8 ApplicationColorIndex(int applicationId); int DomainApplicationId(const Utf8String &data); Utf8String ParseString(const MTPstring &data); @@ -108,12 +108,13 @@ struct ContactInfo { Utf8String lastName; Utf8String phoneNumber; TimeId date = 0; + uint8 colorIndex = 0; Utf8String name() const; }; ContactInfo ParseContactInfo(const MTPUser &data); -int ContactColorIndex(const ContactInfo &data); +uint8 ContactColorIndex(const ContactInfo &data); struct Photo { uint64 id = 0; @@ -217,6 +218,7 @@ struct User { BareId bareId = 0; ContactInfo info; Utf8String username; + uint8 colorIndex = 0; bool isBot = false; bool isSelf = false; bool isReplies = false; @@ -236,6 +238,7 @@ struct Chat { ChannelId migratedToChannelId = 0; Utf8String title; Utf8String username; + uint8 colorIndex = 0; bool isBroadcast = false; bool isSupergroup = false; @@ -249,6 +252,7 @@ struct Peer { PeerId id() const; Utf8String name() const; MTPInputPeer input() const; + uint8 colorIndex() const; const User *user() const; const Chat *chat() const; @@ -746,6 +750,7 @@ struct DialogInfo { int32 topMessageId = 0; TimeId topMessageDate = 0; PeerId peerId = 0; + uint8 colorIndex = 0; MTPInputPeer migratedFromInput = MTP_inputPeerEmpty(); ChannelId migratedToChannelId = 0; diff --git a/Telegram/SourceFiles/export/output/export_output_html.cpp b/Telegram/SourceFiles/export/output/export_output_html.cpp index e42aced3e..28018e888 100644 --- a/Telegram/SourceFiles/export/output/export_output_html.cpp +++ b/Telegram/SourceFiles/export/output/export_output_html.cpp @@ -25,7 +25,7 @@ constexpr auto kPersonalUserpicSize = 90; constexpr auto kEntryUserpicSize = 48; constexpr auto kServiceMessagePhotoSize = 60; constexpr auto kHistoryUserpicSize = 42; -constexpr auto kSavedMessagesColorIndex = 3; +constexpr auto kSavedMessagesColorIndex = uint8(3); constexpr auto kJoinWithinSeconds = 900; constexpr auto kPhotoMaxWidth = 520; constexpr auto kPhotoMaxHeight = 520; @@ -351,7 +351,7 @@ QByteArray FormatTimeText(TimeId date) { namespace details { struct UserpicData { - int colorIndex = 0; + uint8 colorIndex = 0; int pixelSize = 0; QString imageLink; QString largeLink; @@ -991,7 +991,7 @@ QByteArray HtmlWriter::Wrap::pushServiceMessage( result.append(popTag()); if (photo) { auto userpic = UserpicData(); - userpic.colorIndex = Data::PeerColorIndex(dialog.peerId); + userpic.colorIndex = dialog.colorIndex; userpic.firstName = dialog.name; userpic.lastName = dialog.lastName; userpic.pixelSize = kServiceMessagePhotoSize; @@ -2170,7 +2170,7 @@ Result HtmlWriter::start( Result HtmlWriter::writePersonal(const Data::PersonalInfo &data) { Expects(_summary != nullptr); - _selfColorIndex = Data::PeerColorIndex(data.user.info.userId); + _selfColorIndex = data.user.info.colorIndex; if (_settings.types & Settings::Type::Userpics) { _delayedPersonalInfo = std::make_unique(data); return Result::Success(); diff --git a/Telegram/SourceFiles/export/output/export_output_html.h b/Telegram/SourceFiles/export/output/export_output_html.h index c1dee2ffd..27d68a54a 100644 --- a/Telegram/SourceFiles/export/output/export_output_html.h +++ b/Telegram/SourceFiles/export/output/export_output_html.h @@ -150,7 +150,7 @@ private: bool _summaryNeedDivider = false; bool _haveSections = false; - int _selfColorIndex = 0; + uint8 _selfColorIndex = 0; std::unique_ptr _delayedPersonalInfo; int _userpicsCount = 0; diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index 7ba64d26f..11fcddf29 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -110,9 +110,9 @@ void HistoryMessageVia::resize(int32 availw) const { HiddenSenderInfo::HiddenSenderInfo(const QString &name, bool external) : name(name) -, colorPeerId(Data::FakePeerIdForJustName(name)) +, colorIndex(Data::DecideColorIndex(Data::FakePeerIdForJustName(name))) , emptyUserpic( - Ui::EmptyUserpic::UserpicColor(Data::PeerColorIndex(colorPeerId)), + Ui::EmptyUserpic::UserpicColor(colorIndex), (external ? Ui::EmptyUserpic::ExternalName() : name)) { @@ -400,13 +400,13 @@ bool HistoryMessageReply::updateData( if (resolvedMessage) { const auto peer = resolvedMessage->history()->peer; - _colorKey = (!holder->out() + _colorIndexPlusOne = (!holder->out() && (peer->isMegagroup() || peer->isChat()) && resolvedMessage->from()->isUser()) - ? resolvedMessage->from()->id - : PeerId(); + ? (resolvedMessage->from()->colorIndex() + 1) + : uint8(); } else if (!resolvedStory) { - _unavailable = true; + _unavailable = 1; } const auto media = resolvedMessage @@ -419,9 +419,9 @@ bool HistoryMessageReply::updateData( } } else if (force) { if (_fields.messageId || _fields.storyId) { - _unavailable = true; + _unavailable = 1; } - _colorKey = 0; + _colorIndexPlusOne = 0; spoiler = nullptr; } if (force) { @@ -502,7 +502,7 @@ void HistoryMessageReply::clearData(not_null holder) { resolvedStory.get()); resolvedStory = nullptr; } - _unavailable = true; + _unavailable = 1; refreshReplyToMedia(); } @@ -663,8 +663,8 @@ void HistoryMessageReply::paint( const auto outerWidth = w + 2 * x; const auto &bar = !inBubble ? st->msgImgReplyBarColor() - : _colorKey - ? HistoryView::FromNameFg(context, _colorKey) + : _colorIndexPlusOne + ? HistoryView::FromNameFg(context, _colorIndexPlusOne - 1) : stm->msgReplyBarColor; const auto rbar = style::rtlrect( x + st::msgReplyBarPos.x(), @@ -735,8 +735,10 @@ void HistoryMessageReply::paint( if (w > st::msgReplyBarSkip + previewSkip) { p.setPen(!inBubble ? st->msgImgReplyBarColor() - : _colorKey - ? HistoryView::FromNameFg(context, _colorKey) + : _colorIndexPlusOne + ? HistoryView::FromNameFg( + context, + _colorIndexPlusOne - 1) : stm->msgServiceFg); _name.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top(), w - st::msgReplyBarSkip - previewSkip, w + 2 * x); if (originalVia && w > st::msgReplyBarSkip + previewSkip + _name.maxWidth() + st::msgServiceFont->spacew) { diff --git a/Telegram/SourceFiles/history/history_item_components.h b/Telegram/SourceFiles/history/history_item_components.h index c46f838b8..1f10c733d 100644 --- a/Telegram/SourceFiles/history/history_item_components.h +++ b/Telegram/SourceFiles/history/history_item_components.h @@ -90,7 +90,7 @@ public: QString name; QString firstName; QString lastName; - PeerId colorPeerId = 0; + uint8 colorIndex = 0; Ui::EmptyUserpic emptyUserpic; mutable Data::CloudImage customUserpic; @@ -291,9 +291,6 @@ struct HistoryMessageReply bool inBubble) const; void unloadPersistentAnimation(); - [[nodiscard]] PeerId colorKey() const { - return _colorKey; - } [[nodiscard]] PeerId externalPeerId() const { return _fields.externalPeerId; } @@ -337,14 +334,14 @@ struct HistoryMessageReply private: ReplyFields _fields; - PeerId _colorKey = 0; ClickHandlerPtr _link; mutable Ui::Text::String _name; mutable Ui::Text::String _text; mutable PeerData *_externalSender = nullptr; mutable int _maxWidth = 0; mutable int _nameVersion = 0; - bool _unavailable = false; + uint8 _colorIndexPlusOne : 7 = 0; + uint8 _unavailable : 1 = 0; }; diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 8b86fa2e8..60d18d46a 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -368,33 +368,8 @@ QString FastReplyText() { style::color FromNameFg( const Ui::ChatPaintContext &context, - PeerId peerId) { - const auto st = context.st; - if (context.selected()) { - const style::color colors[] = { - st->historyPeer1NameFgSelected(), - st->historyPeer2NameFgSelected(), - st->historyPeer3NameFgSelected(), - st->historyPeer4NameFgSelected(), - st->historyPeer5NameFgSelected(), - st->historyPeer6NameFgSelected(), - st->historyPeer7NameFgSelected(), - st->historyPeer8NameFgSelected(), - }; - return colors[Data::PeerColorIndex(peerId)]; - } else { - const style::color colors[] = { - st->historyPeer1NameFg(), - st->historyPeer2NameFg(), - st->historyPeer3NameFg(), - st->historyPeer4NameFg(), - st->historyPeer5NameFg(), - st->historyPeer6NameFg(), - st->historyPeer7NameFg(), - st->historyPeer8NameFg(), - }; - return colors[Data::PeerColorIndex(peerId)]; - } + uint8 colorIndex) { + return Ui::FromNameFg(context.st, context.selected(), colorIndex); } struct Message::CommentsButton { @@ -1355,7 +1330,7 @@ void Message::paintFromName( const auto service = (context.outbg || item->isPost()); const auto st = context.st; const auto nameFg = !service - ? FromNameFg(context, from ? from->id : info->colorPeerId) + ? FromNameFg(context, from ? from->colorIndex() : info->colorIndex) : item->isSponsored() ? st->boxTextFgGood() : stm->msgServiceFg; @@ -1630,7 +1605,7 @@ void Message::paintText( .availableWidth = trect.width(), .palette = &stm->textPalette, .pre = stm->preCache.get(), - .blockquote = stm->blockquoteCache.get(), + .blockquote = stm->quoteCache.get(), .colors = context.st->highlightColors(), .spoiler = Ui::Text::DefaultSpoilerCache(), .now = context.now, diff --git a/Telegram/SourceFiles/history/view/history_view_message.h b/Telegram/SourceFiles/history/view/history_view_message.h index 1efc0892b..9c2a81ea4 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.h +++ b/Telegram/SourceFiles/history/view/history_view_message.h @@ -58,7 +58,7 @@ struct BottomRippleMask { [[nodiscard]] style::color FromNameFg( const Ui::ChatPaintContext &context, - PeerId peerId); + uint8 colorIndex); class Message final : public Element { public: diff --git a/Telegram/SourceFiles/history/view/media/history_view_contact.cpp b/Telegram/SourceFiles/history/view/media/history_view_contact.cpp index d33f1ba8a..7b0ac35b9 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_contact.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_contact.cpp @@ -122,7 +122,7 @@ QSize Contact::countOptimalSize() { } else { const auto full = _name.toString(); _photoEmpty = std::make_unique( - Ui::EmptyUserpic::UserpicColor(Data::PeerColorIndex(_userId + Ui::EmptyUserpic::UserpicColor(Data::DecideColorIndex(_userId ? peerFromUser(_userId) : Data::FakePeerIdForJustName(full))), full); diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index 165f79dea..7184a7fc0 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -749,7 +749,7 @@ void Document::draw( .availableWidth = captionw, .palette = &stm->textPalette, .pre = stm->preCache.get(), - .blockquote = stm->blockquoteCache.get(), + .blockquote = stm->quoteCache.get(), .colors = context.st->highlightColors(), .spoiler = Ui::Text::DefaultSpoilerCache(), .now = context.now, diff --git a/Telegram/SourceFiles/history/view/media/history_view_extended_preview.cpp b/Telegram/SourceFiles/history/view/media/history_view_extended_preview.cpp index f34ca7574..a4695e4a1 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_extended_preview.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_extended_preview.cpp @@ -236,7 +236,7 @@ void ExtendedPreview::draw(Painter &p, const PaintContext &context) const { .availableWidth = captionw, .palette = &stm->textPalette, .pre = stm->preCache.get(), - .blockquote = stm->blockquoteCache.get(), + .blockquote = stm->quoteCache.get(), .colors = context.st->highlightColors(), .spoiler = Ui::Text::DefaultSpoilerCache(), .now = context.now, diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp index cd475f2d2..04a168852 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp @@ -710,7 +710,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const { .availableWidth = captionw, .palette = &stm->textPalette, .pre = stm->preCache.get(), - .blockquote = stm->blockquoteCache.get(), + .blockquote = stm->quoteCache.get(), .colors = context.st->highlightColors(), .spoiler = Ui::Text::DefaultSpoilerCache(), .now = context.now, diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp index 2333e334d..fc7263386 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp @@ -368,7 +368,7 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const { .availableWidth = captionw, .palette = &stm->textPalette, .pre = stm->preCache.get(), - .blockquote = stm->blockquoteCache.get(), + .blockquote = stm->quoteCache.get(), .colors = context.st->highlightColors(), .spoiler = Ui::Text::DefaultSpoilerCache(), .now = context.now, diff --git a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp index 5e912d33c..a83991bf6 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp @@ -406,7 +406,7 @@ void Photo::draw(Painter &p, const PaintContext &context) const { .availableWidth = captionw, .palette = &stm->textPalette, .pre = stm->preCache.get(), - .blockquote = stm->blockquoteCache.get(), + .blockquote = stm->quoteCache.get(), .colors = context.st->highlightColors(), .spoiler = Ui::Text::DefaultSpoilerCache(), .now = context.now, diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp index 1bbaad755..d1d1cafad 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp @@ -161,7 +161,8 @@ QImage *ItemBase::getResultThumb(Data::FileOrigin origin) const { QPixmap ItemBase::getResultContactAvatar(int width, int height) const { if (_result->_type == Result::Type::Contact) { auto result = Ui::EmptyUserpic( - Ui::EmptyUserpic::UserpicColor(BareId(qHash(_result->_id))), + Ui::EmptyUserpic::UserpicColor(Ui::EmptyUserpic::ColorIndex( + BareId(qHash(_result->_id)))), _result->getLayoutTitle() ).generate(width); if (result.height() != height * cIntRetinaFactor()) { diff --git a/Telegram/SourceFiles/ui/chat/chat_style.cpp b/Telegram/SourceFiles/ui/chat/chat_style.cpp index b1e22f808..6c1510116 100644 --- a/Telegram/SourceFiles/ui/chat/chat_style.cpp +++ b/Telegram/SourceFiles/ui/chat/chat_style.cpp @@ -25,7 +25,7 @@ void EnsureCorners( const style::color &color, const style::color *shadow = nullptr) { if (corners.p[0].isNull()) { - corners = Ui::PrepareCornerPixmaps(radius, color, shadow); + corners = PrepareCornerPixmaps(radius, color, shadow); } } @@ -482,7 +482,7 @@ void ChatStyle::applyAdjustedServiceBg(QColor serviceBg) { msgServiceBg().set(uchar(r), uchar(g), uchar(b), uchar(a)); } -std::span ChatStyle::highlightColors() const { +std::span ChatStyle::highlightColors() const { if (_highlightColors.empty()) { const auto push = [&](const style::color &color) { _highlightColors.push_back({ &color->p, &color->p }); @@ -523,7 +523,8 @@ void ChatStyle::assignPalette(not_null palette) { for (auto &style : _messageStyles) { style.msgBgCornersSmall = {}; style.msgBgCornersLarge = {}; - style.blockquoteCache = nullptr; + style.quoteCache = nullptr; + style.replyCache = nullptr; style.preCache = nullptr; } for (auto &style : _imageStyles) { @@ -560,7 +561,7 @@ const CornersPixmaps &ChatStyle::serviceBgCornersNormal() const { const CornersPixmaps &ChatStyle::serviceBgCornersInverted() const { if (_serviceBgCornersInverted.p[0].isNull()) { - _serviceBgCornersInverted = Ui::PrepareInvertedCornerPixmaps( + _serviceBgCornersInverted = PrepareInvertedCornerPixmaps( HistoryServiceMsgInvertedRadius(), msgServiceBg()); } @@ -580,12 +581,12 @@ const MessageStyle &ChatStyle::messageStyle(bool outbg, bool selected) const { result.msgBg, &result.msgShadow); EnsureBlockquoteCache( - result.blockquoteCache, + result.replyCache, result.msgReplyBarColor); const auto preBgOverride = [&] { const auto withBg = [&](const QColor &color) { - return Ui::CountContrast(windowBg()->c, color); + return CountContrast(windowBg()->c, color); }; const auto dark = (withBg({ 0, 0, 0 }) < withBg({ 255, 255, 255 })); return dark ? QColor(0, 0, 0, 192) : std::optional(); @@ -621,9 +622,44 @@ const MessageImageStyle &ChatStyle::imageStyle(bool selected) const { result.msgShadowCornersLarge, BubbleRadiusLarge(), result.msgShadow); + return result; } +not_null ChatStyle::serviceQuoteCache() const { + EnsureBlockquoteCache(_serviceQuoteCache, msgServiceFg()); + return _serviceQuoteCache.get(); +} + +not_null ChatStyle::serviceReplyCache() const { + EnsureBlockquoteCache(_serviceReplyCache, msgServiceFg()); + return _serviceReplyCache.get(); +} + +not_null ChatStyle::coloredQuoteCache( + bool selected, + uint8 colorIndex) const { + return coloredCache(_coloredQuoteCaches, selected, colorIndex); +} + +not_null ChatStyle::coloredReplyCache( + bool selected, + uint8 colorIndex) const { + return coloredCache(_coloredReplyCaches, selected, colorIndex); +} + +not_null ChatStyle::coloredCache( + ColoredQuotePaintCaches &caches, + bool selected, + uint8 colorIndex) const { + Expects(colorIndex >= 0 && colorIndex < kColorIndexCount); + + const auto shift = (selected ? kColorIndexCount : 0); + auto &cache = caches[shift + colorIndex]; + EnsureBlockquoteCache(cache, FromNameFg(this, selected, colorIndex)); + return cache.get(); +} + const CornersPixmaps &ChatStyle::msgBotKbOverBgAddCornersSmall() const { EnsureCorners( _msgBotKbOverBgAddCornersSmall, @@ -751,6 +787,50 @@ void ChatStyle::make( make(imageSelected().*my, originalSelected); } +uint8 DecideColorIndex(uint64 id) { + return id % kColorIndexCount; +} + +uint8 ColorIndexToPaletteIndex(uint8 colorIndex) { + Expects(colorIndex >= 0 && colorIndex < kColorIndexCount); + + const int8 map[] = { 0, 7, 4, 1, 6, 3, 5 }; + return map[colorIndex]; +} + +style::color FromNameFg( + not_null st, + bool selected, + uint8 colorIndex) { + Expects(colorIndex >= 0 && colorIndex < kColorIndexCount); + + if (selected) { + const style::color colors[] = { + st->historyPeer1NameFgSelected(), + st->historyPeer2NameFgSelected(), + st->historyPeer3NameFgSelected(), + st->historyPeer4NameFgSelected(), + st->historyPeer5NameFgSelected(), + st->historyPeer6NameFgSelected(), + st->historyPeer7NameFgSelected(), + st->historyPeer8NameFgSelected(), + }; + return colors[ColorIndexToPaletteIndex(colorIndex)]; + } else { + const style::color colors[] = { + st->historyPeer1NameFg(), + st->historyPeer2NameFg(), + st->historyPeer3NameFg(), + st->historyPeer4NameFg(), + st->historyPeer5NameFg(), + st->historyPeer6NameFg(), + st->historyPeer7NameFg(), + st->historyPeer8NameFg(), + }; + return colors[ColorIndexToPaletteIndex(colorIndex)]; + } +} + void FillComplexOverlayRect( QPainter &p, QRect rect, diff --git a/Telegram/SourceFiles/ui/chat/chat_style.h b/Telegram/SourceFiles/ui/chat/chat_style.h index dda612b66..4c9510e07 100644 --- a/Telegram/SourceFiles/ui/chat/chat_style.h +++ b/Telegram/SourceFiles/ui/chat/chat_style.h @@ -27,6 +27,8 @@ class ChatTheme; class ChatStyle; struct BubblePattern; +inline constexpr auto kColorIndexCount = uint8(7); + struct MessageStyle { CornersPixmaps msgBgCornersSmall; CornersPixmaps msgBgCornersLarge; @@ -76,9 +78,9 @@ struct MessageStyle { style::icon historyPollChoiceRight = { Qt::Uninitialized }; style::icon historyTranscribeIcon = { Qt::Uninitialized }; style::icon historyTranscribeHide = { Qt::Uninitialized }; - std::unique_ptr blockquoteCache; + std::unique_ptr quoteCache; + std::unique_ptr replyCache; std::unique_ptr preCache; - }; struct MessageImageStyle { @@ -170,7 +172,7 @@ public: void applyCustomPalette(const style::palette *palette); void applyAdjustedServiceBg(QColor serviceBg); - [[nodiscard]] std::span highlightColors() const; + [[nodiscard]] std::span highlightColors() const; [[nodiscard]] rpl::producer<> paletteChanged() const { return _paletteChanged.events(); @@ -200,6 +202,17 @@ public: bool selected) const; [[nodiscard]] const MessageImageStyle &imageStyle(bool selected) const; + [[nodiscard]] auto serviceQuoteCache() const + -> not_null; + [[nodiscard]] auto serviceReplyCache() const + -> not_null; + [[nodiscard]] not_null coloredQuoteCache( + bool selected, + uint8 colorIndex) const; + [[nodiscard]] not_null coloredReplyCache( + bool selected, + uint8 colorIndex) const; + [[nodiscard]] const CornersPixmaps &msgBotKbOverBgAddCornersSmall() const; [[nodiscard]] const CornersPixmaps &msgBotKbOverBgAddCornersLarge() const; [[nodiscard]] const CornersPixmaps &msgSelectOverlayCorners( @@ -285,8 +298,16 @@ public: } private: + using ColoredQuotePaintCaches = std::array< + std::unique_ptr, + kColorIndexCount * 2>; void assignPalette(not_null palette); + [[nodiscard]] not_null coloredCache( + ColoredQuotePaintCaches &caches, + bool selected, + uint8 colorIndex) const; + void make(style::color &my, const style::color &original) const; void make(style::icon &my, const style::icon &original) const; void make( @@ -336,7 +357,11 @@ private: mutable CornersPixmaps _msgSelectOverlayCorners[ int(CachedCornerRadius::kCount)]; - mutable std::vector _highlightColors; + mutable std::vector _highlightColors; + mutable std::unique_ptr _serviceQuoteCache; + mutable std::unique_ptr _serviceReplyCache; + mutable ColoredQuotePaintCaches _coloredQuoteCaches; + mutable ColoredQuotePaintCaches _coloredReplyCaches; style::TextPalette _historyPsaForwardPalette; style::TextPalette _imgReplyTextPalette; @@ -371,6 +396,14 @@ private: }; +[[nodiscard]] uint8 DecideColorIndex(uint64 id); +[[nodiscard]] uint8 ColorIndexToPaletteIndex(uint8 colorIndex); + +[[nodiscard]] style::color FromNameFg( + not_null st, + bool selected, + uint8 colorIndex); + void FillComplexOverlayRect( QPainter &p, QRect rect, diff --git a/Telegram/SourceFiles/ui/controls/userpic_button.cpp b/Telegram/SourceFiles/ui/controls/userpic_button.cpp index 224fd7a35..bad612d20 100644 --- a/Telegram/SourceFiles/ui/controls/userpic_button.cpp +++ b/Telegram/SourceFiles/ui/controls/userpic_button.cpp @@ -1050,8 +1050,7 @@ void UserpicButton::prepareUserpicPixmap() { } else { const auto user = _peer->asUser(); auto empty = Ui::EmptyUserpic( - Ui::EmptyUserpic::UserpicColor( - Data::PeerColorIndex(_peer->id)), + Ui::EmptyUserpic::UserpicColor(_peer->colorIndex()), ((user && user->isInaccessible()) ? Ui::EmptyUserpic::InaccessibleName() : _peer->name())); diff --git a/Telegram/SourceFiles/ui/empty_userpic.cpp b/Telegram/SourceFiles/ui/empty_userpic.cpp index a319c3454..7c46b7826 100644 --- a/Telegram/SourceFiles/ui/empty_userpic.cpp +++ b/Telegram/SourceFiles/ui/empty_userpic.cpp @@ -7,8 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "ui/empty_userpic.h" -#include "ui/emoji_config.h" +#include "ui/chat/chat_style.h" #include "ui/effects/animation_value.h" +#include "ui/emoji_config.h" #include "ui/painter.h" #include "ui/ui_utility.h" #include "styles/style_chat.h" @@ -221,13 +222,11 @@ QString EmptyUserpic::InaccessibleName() { return QChar(0) + u"inaccessible"_q; } -int EmptyUserpic::ColorIndex(uint64 id) { - const auto index = id % 7; - const int map[] = { 0, 7, 4, 1, 6, 3, 5 }; - return map[index]; +uint8 EmptyUserpic::ColorIndex(uint64 id) { + return DecideColorIndex(id); } -EmptyUserpic::BgColors EmptyUserpic::UserpicColor(int id) { +EmptyUserpic::BgColors EmptyUserpic::UserpicColor(uint8 colorIndex) { const EmptyUserpic::BgColors colors[] = { { st::historyPeer1UserpicBg, st::historyPeer1UserpicBg2 }, { st::historyPeer2UserpicBg, st::historyPeer2UserpicBg2 }, @@ -238,7 +237,7 @@ EmptyUserpic::BgColors EmptyUserpic::UserpicColor(int id) { { st::historyPeer7UserpicBg, st::historyPeer7UserpicBg2 }, { st::historyPeer8UserpicBg, st::historyPeer8UserpicBg2 }, }; - return colors[id]; + return colors[ColorIndexToPaletteIndex(colorIndex)]; } void EmptyUserpic::paint( diff --git a/Telegram/SourceFiles/ui/empty_userpic.h b/Telegram/SourceFiles/ui/empty_userpic.h index 2f9b9856b..f71335a6a 100644 --- a/Telegram/SourceFiles/ui/empty_userpic.h +++ b/Telegram/SourceFiles/ui/empty_userpic.h @@ -18,8 +18,9 @@ public: const style::color color2; }; - [[nodiscard]] static int ColorIndex(uint64 id); - [[nodiscard]] static EmptyUserpic::BgColors UserpicColor(int id); + [[nodiscard]] static uint8 ColorIndex(uint64 id); + [[nodiscard]] static EmptyUserpic::BgColors UserpicColor( + uint8 colorIndex); [[nodiscard]] static QString ExternalName(); [[nodiscard]] static QString InaccessibleName(); diff --git a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp index 82698486b..a3ea8a708 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp @@ -986,7 +986,7 @@ void Generator::paintService(QString text) { } void Generator::paintUserpic(int x, int y, Row::Type type, int index, QString letters) { - const auto colorIndex = Ui::EmptyUserpic::ColorIndex(index); + const auto colorIndex = Ui::DecideColorIndex(index); const auto colors = Ui::EmptyUserpic::UserpicColor(colorIndex); auto userpic = Ui::EmptyUserpic(colors, letters);