diff --git a/Telegram/SourceFiles/core/core_settings.cpp b/Telegram/SourceFiles/core/core_settings.cpp index fcc262f174..0a46da18ab 100644 --- a/Telegram/SourceFiles/core/core_settings.cpp +++ b/Telegram/SourceFiles/core/core_settings.cpp @@ -66,6 +66,21 @@ constexpr auto kRecentEmojiLimit = 42; return result; } +[[nodiscard]] quint32 SerializeColor(QColor color) { + return (quint32(std::clamp(color.alpha(), 0, 255)) << 24) + | (quint32(std::clamp(color.red(), 0, 255)) << 16) + | (quint32(std::clamp(color.green(), 0, 255)) << 8) + | quint32(std::clamp(color.blue(), 0, 255)); +} + +[[nodiscard]] QColor DeserializeColor(quint32 value) { + return QColor( + (value >> 16) & 0xFF, + (value >> 8) & 0xFF, + value & 0xFF, + (value >> 24) & 0xFF); +} + } // namespace Settings::Settings() @@ -236,6 +251,10 @@ QByteArray Settings::serialize() const { for (const auto &id : _accountsOrder) { stream << quint64(id); } + + stream + << SerializeColor(_customAppIcon.color) + << quint64(_customAppIcon.digest); } return result; } @@ -325,6 +344,8 @@ void Settings::addFromSerialized(const QByteArray &serialized) { qint32 macWarnBeforeQuit = _macWarnBeforeQuit ? 1 : 0; qint32 accountsOrderCount = 0; std::vector accountsOrder; + quint32 customAppIconColor = SerializeColor(_customAppIcon.color); + quint64 customAppIconDigest = _customAppIcon.digest; stream >> themesAccentColors; if (!stream.atEnd()) { @@ -506,6 +527,11 @@ void Settings::addFromSerialized(const QByteArray &serialized) { } } } + if (!stream.atEnd()) { + stream + >> customAppIconColor + >> customAppIconDigest; + } if (stream.status() != QDataStream::Ok) { LOG(("App Error: " "Bad data for Core::Settings::constructFromSerialized()")); @@ -662,6 +688,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) { case Media::Player::OrderMode::Shuffle: _playerOrderMode = uncheckedPlayerOrderMode; break; } _macWarnBeforeQuit = macWarnBeforeQuit ? 1 : 0; + _customAppIcon = { DeserializeColor(customAppIconColor), customAppIconDigest }; } QString Settings::getSoundPath(const QString &key) const { diff --git a/Telegram/SourceFiles/core/core_settings.h b/Telegram/SourceFiles/core/core_settings.h index f411bd4bf4..4a49699f15 100644 --- a/Telegram/SourceFiles/core/core_settings.h +++ b/Telegram/SourceFiles/core/core_settings.h @@ -51,6 +51,11 @@ struct WindowPosition { int h = 0; }; +struct CustomAppIcon { + QColor color; + uint64 digest = 0; +}; + class Settings final { public: enum class ScreenCorner { @@ -669,6 +674,12 @@ public: [[nodiscard]] bool macWarnBeforeQuit() const { return _macWarnBeforeQuit; } + void setCustomAppIcon(CustomAppIcon icon) { + _customAppIcon = icon; + } + [[nodiscard]] CustomAppIcon customAppIcon() const { + return _customAppIcon; + } [[nodiscard]] static bool ThirdColumnByDefault(); [[nodiscard]] static float64 DefaultDialogsWidthRatio(); @@ -775,6 +786,7 @@ private: rpl::variable _playerOrderMode; bool _macWarnBeforeQuit = true; std::vector _accountsOrder; + CustomAppIcon _customAppIcon; bool _tabbedReplacedWithInfo = false; // per-window rpl::event_stream _tabbedReplacedWithInfoValue; // per-window diff --git a/Telegram/SourceFiles/settings/settings_chat.cpp b/Telegram/SourceFiles/settings/settings_chat.cpp index 0220b8626e..21731a804c 100644 --- a/Telegram/SourceFiles/settings/settings_chat.cpp +++ b/Telegram/SourceFiles/settings/settings_chat.cpp @@ -286,8 +286,6 @@ void ColorsPalette::show( int selected, int customLightnessMin, int customLightnessMax) { - Expects(selected >= 0 && selected < colors.size()); - _outer->show(anim::type::instant); while (_buttons.size() > colors.size()) { @@ -1029,23 +1027,51 @@ void SetupAppIcon( not_null container) { AddSkip(container, st::settingsPrivacySkip); - AddSubsectionTitle(container, rpl::single(u"App Icon"_q)); + container->add( + object_ptr( + container, + rpl::single(u"App Icon"_q), + st::settingsSubsectionTitle), + (st::settingsSubsectionTitlePadding + - QMargins(0, 0, 0, st::settingsSubsectionTitlePadding.bottom()))); const auto palette = Ui::CreateChild( container.get(), container.get()); - auto list = Window::Theme::DefaultAccentColors( - Window::Theme::EmbeddedType::Night); const auto original = QColor(29, 148, 208); - list[0] = original; - palette->show(std::move(list), 0, 0, 255); + const auto refresh = [=](uint64 currentDigest) { + auto list = Window::Theme::DefaultAccentColors( + Window::Theme::EmbeddedType::Night); + list[0] = original; + const auto current = Core::App().settings().customAppIcon(); + const auto selected = !currentDigest + ? 0 + : (currentDigest != current.digest) + ? -1 + : std::min( + int(ranges::find(list, current.color) - begin(list)), + int(size(list)) - 1); + if (selected == size(list) - 1) { + list[selected] = current.color; + } + palette->show(std::move(list), selected, 0, 255); + }; + refresh(base::CurrentCustomAppIconDigest().value_or(0)); const auto logo = QImage(":/gui/art/logo_256.png").convertToFormat( QImage::Format_ARGB32); palette->selected( ) | rpl::start_with_next([=](QColor color) { if (color == original) { - base::ClearCustomAppIcon(); + const auto success = base::ClearCustomAppIcon(); + if (success) { + Core::App().settings().setCustomAppIcon({}); + Core::App().saveSettingsDelayed(); + refresh(0); + } + Ui::Toast::Show(success + ? "Icon cleared. Restarting the Dock." + : "Icon clear failed. See log.txt for details."); } else { auto colorizer = style::colorizer{ .hueThreshold = 64, @@ -1060,11 +1086,20 @@ void SetupAppIcon( &colorizer.now.value); auto image = logo; style::colorize(image, colorizer); - base::SetCustomAppIcon(std::move(image)); + const auto digest = base::SetCustomAppIcon(std::move(image)); + if (digest) { + Core::App().settings().setCustomAppIcon({ color, *digest }); + Core::App().saveSettingsDelayed(); + refresh(*digest); + } + Ui::Toast::Show(digest + ? "Icon updated. Restarting the Dock." + : "Icon update failed. See log.txt for details."); } }, container->lifetime()); AddSkip(container); + AddDivider(container); } #endif // Q_OS_MAC && !OS_MAC_STORE diff --git a/Telegram/lib_base b/Telegram/lib_base index 7253d8f098..2461c5ad4a 160000 --- a/Telegram/lib_base +++ b/Telegram/lib_base @@ -1 +1 @@ -Subproject commit 7253d8f09883df51705c358b1f8ff50ba7eda8e6 +Subproject commit 2461c5ad4a929825ff79bc94172334306176f328