From eb0bfcec90d2d87309f21e5c689a6761e64a479c Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 3 Jul 2026 21:06:29 +0300 Subject: [PATCH] Added chat theme bubble gradient to all chats. --- Telegram/SourceFiles/ui/chat/chat_theme.cpp | 12 +++++++----- Telegram/SourceFiles/ui/chat/chat_theme.h | 2 ++ .../window/themes/window_themes_chat.cpp | 12 ++++++------ .../window/themes/window_themes_chat.h | 4 ++++ .../window/window_session_controller.cpp | 16 ++++++++++++++++ .../window/window_session_controller.h | 1 + 6 files changed, 36 insertions(+), 11 deletions(-) diff --git a/Telegram/SourceFiles/ui/chat/chat_theme.cpp b/Telegram/SourceFiles/ui/chat/chat_theme.cpp index 436ecd9980..624b5117c5 100644 --- a/Telegram/SourceFiles/ui/chat/chat_theme.cpp +++ b/Telegram/SourceFiles/ui/chat/chat_theme.cpp @@ -247,8 +247,9 @@ constexpr auto kMinAcceptableContrast = 1.14;// 4.5; } } -[[nodiscard]] QImage PrepareBubblesBackground( - const ChatThemeBubblesData &data) { +} // namespace + +QImage PrepareBubblesBackground(const ChatThemeBubblesData &data) { if (data.colors.size() < 2) { return QImage(); } @@ -256,8 +257,6 @@ constexpr auto kMinAcceptableContrast = 1.14;// 4.5; return Images::GenerateLinearGradient(QSize(kSize, kSize), data.colors); } -} // namespace - bool operator==(const ChatThemeBackground &a, const ChatThemeBackground &b) { return (a.key == b.key) && (a.prepared.cacheKey() == b.prepared.cacheKey()) @@ -551,7 +550,10 @@ void ChatTheme::setBubblesBackground(QImage image) { : _bubblesBackground.area), }); if (!_bubblesBackgroundPattern) { - _bubblesBackgroundPattern = PrepareBubblePattern(palette()); + const auto use = _palette + ? _palette.get() + : style::main_palette::get().get(); + _bubblesBackgroundPattern = PrepareBubblePattern(use); } _bubblesBackgroundPattern->pixmap = _bubblesBackground.pixmap; // setBubblesBackground called only from background thread. diff --git a/Telegram/SourceFiles/ui/chat/chat_theme.h b/Telegram/SourceFiles/ui/chat/chat_theme.h index 0f328e410a..2aad3ded3e 100644 --- a/Telegram/SourceFiles/ui/chat/chat_theme.h +++ b/Telegram/SourceFiles/ui/chat/chat_theme.h @@ -287,6 +287,8 @@ struct BackgroundImageFields { int rotation); [[nodiscard]] ChatThemeBackground PrepareBackgroundImage( const ChatThemeBackgroundData &data); +[[nodiscard]] QImage PrepareBubblesBackground( + const ChatThemeBubblesData &data); [[nodiscard]] QImage PrepareGiftSymbol( const std::unique_ptr &emoji); diff --git a/Telegram/SourceFiles/window/themes/window_themes_chat.cpp b/Telegram/SourceFiles/window/themes/window_themes_chat.cpp index 7f6378f00a..acb795cc96 100644 --- a/Telegram/SourceFiles/window/themes/window_themes_chat.cpp +++ b/Telegram/SourceFiles/window/themes/window_themes_chat.cpp @@ -36,7 +36,9 @@ namespace { return result; } -[[nodiscard]] std::optional SettingsTypeFor( +} // namespace + +std::optional ChatThemeVariant( const Data::CloudTheme &theme, bool dark) { const auto type = dark @@ -52,8 +54,6 @@ namespace { : std::nullopt; } -} // namespace - Ui::ChatThemeBubblesData PrepareBubblesData( const Data::CloudTheme &theme, Data::CloudThemeType type) { @@ -71,7 +71,7 @@ Ui::ChatThemeBubblesData PrepareBubblesData( std::unique_ptr PreviewFromChatTheme( const Data::CloudTheme &theme, bool dark) { - const auto used = SettingsTypeFor(theme, dark); + const auto used = ChatThemeVariant(theme, dark); if (!used) { return nullptr; } @@ -110,7 +110,7 @@ void ApplyChatTheme( not_null controller, const Data::CloudTheme &theme, bool dark) { - const auto used = SettingsTypeFor(theme, dark); + const auto used = ChatThemeVariant(theme, dark); if (!used) { return; } @@ -139,7 +139,7 @@ void CheckChatThemeWallPaper(not_null controller) { if (cloud.emoticon.isEmpty() || cloud.settings.empty()) { return; } - const auto used = SettingsTypeFor(cloud, IsNightMode()); + const auto used = ChatThemeVariant(cloud, IsNightMode()); if (!used) { return; } diff --git a/Telegram/SourceFiles/window/themes/window_themes_chat.h b/Telegram/SourceFiles/window/themes/window_themes_chat.h index 86a00524b2..0604af6ab4 100644 --- a/Telegram/SourceFiles/window/themes/window_themes_chat.h +++ b/Telegram/SourceFiles/window/themes/window_themes_chat.h @@ -21,6 +21,10 @@ namespace Window::Theme { struct Preview; +[[nodiscard]] std::optional ChatThemeVariant( + const Data::CloudTheme &theme, + bool dark); + [[nodiscard]] Ui::ChatThemeBubblesData PrepareBubblesData( const Data::CloudTheme &theme, Data::CloudThemeType type); diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 52cf6d7177..c0ba7eb387 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -3536,6 +3536,22 @@ void SessionController::pushDefaultChatBackground() { .isPattern = paper.isPattern(), .tile = background->tile(), }); + const auto &cloud = background->themeObject().cloud; + auto bubbles = Ui::ChatThemeBubblesData(); + if (!cloud.emoticon.isEmpty()) { + const auto variant = Theme::ChatThemeVariant( + cloud, + Theme::IsNightMode()); + if (variant) { + bubbles = Theme::PrepareBubblesData(cloud, *variant); + } + } + if (bubbles.colors != _defaultChatThemeBubblesColors) { + _defaultChatThemeBubblesColors = bubbles.colors; + _defaultChatTheme->setBubblesBackground( + Ui::PrepareBubblesBackground(bubbles)); + _defaultChatTheme->finishCreateOnMain(); + } } void SessionController::cacheChatTheme( diff --git a/Telegram/SourceFiles/window/window_session_controller.h b/Telegram/SourceFiles/window/window_session_controller.h index 663f53ff32..a59ae5caf6 100644 --- a/Telegram/SourceFiles/window/window_session_controller.h +++ b/Telegram/SourceFiles/window/window_session_controller.h @@ -864,6 +864,7 @@ private: rpl::event_stream<> _filtersMenuChanged; const std::shared_ptr _defaultChatTheme; + std::vector _defaultChatThemeBubblesColors; base::flat_map _customChatThemes; rpl::event_stream> _cachedThemesStream; rpl::event_stream<> _giftSymbolLoaded;