From e0135e509d0e945f85253e794d7db34774fa7a58 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 19 Sep 2021 11:39:38 +0300 Subject: [PATCH] Allow exporting test chat themes. --- .../SourceFiles/core/local_url_handlers.cpp | 98 +++++++++++++++++++ .../SourceFiles/data/data_cloud_themes.cpp | 18 +++- Telegram/SourceFiles/data/data_cloud_themes.h | 2 +- .../SourceFiles/history/history_widget.cpp | 3 +- .../window/themes/window_theme_editor_box.cpp | 40 ++++---- .../window/themes/window_theme_editor_box.h | 2 + 6 files changed, 139 insertions(+), 24 deletions(-) diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index a72c20b5d..b186e8ac0 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/player/media_player_instance.h" #include "window/window_session_controller.h" #include "window/window_controller.h" +#include "window/themes/window_theme_editor_box.h" // GenerateSlug. #include "settings/settings_common.h" #include "mainwidget.h" #include "main/main_session.h" @@ -469,6 +470,100 @@ bool ShowInviteLink( return true; } +void ExportTestChatTheme( + not_null session, + not_null theme) { + if (!theme->paper + || !theme->paper->isPattern() + || theme->paper->backgroundColors().empty() + || !theme->accentColor + || !theme->paper->hasShareUrl()) { + Ui::Toast::Show("Something went wrong :("); + return; + } + const auto &bg = theme->paper->backgroundColors(); + const auto url = theme->paper->shareUrl(session); + const auto from = url.indexOf("bg/"); + const auto till = url.indexOf("?"); + if (from < 0 || till <= from) { + Ui::Toast::Show("Bad WallPaper link: " + url); + return; + } + + using Flag = MTPaccount_CreateTheme::Flag; + using Setting = MTPDinputThemeSettings::Flag; + using Paper = MTPDwallPaperSettings::Flag; + const auto color = [](const QColor &color) { + const auto red = color.red(); + const auto green = color.green(); + const auto blue = color.blue(); + return int(((uint32(red) & 0xFFU) << 16) + | ((uint32(green) & 0xFFU) << 8) + | (uint32(blue) & 0xFFU)); + }; + const auto colors = [&](const std::vector &colors) { + auto result = QVector(); + result.reserve(colors.size()); + for (const auto &single : colors) { + result.push_back(MTP_int(color(single))); + } + return result; + }; + const auto slug = url.mid(from + 3, till - from - 3); + const auto flags = Flag::f_settings; + const auto settings = Setting::f_wallpaper + | Setting::f_wallpaper_settings + | (theme->outgoingAccentColor + ? Setting::f_outbox_accent_color + : Setting(0)) + | (!theme->outgoingMessagesColors.empty() + ? Setting::f_message_colors + : Setting(0)); + const auto papers = Paper::f_background_color + | Paper::f_intensity + | (bg.size() > 1 + ? Paper::f_second_background_color + : Paper(0)) + | (bg.size() > 2 + ? Paper::f_third_background_color + : Paper(0)) + | (bg.size() > 3 + ? Paper::f_fourth_background_color + : Paper(0)); + session->api().request(MTPaccount_CreateTheme( + MTP_flags(flags), + MTP_string(Window::Theme::GenerateSlug()), + MTP_string(theme->title + " Desktop"), + MTPInputDocument(), + MTP_inputThemeSettings( + MTP_flags(settings), + (theme->basedOnDark + ? MTP_baseThemeTinted() + : MTP_baseThemeClassic()), + MTP_int(color(theme->accentColor.value_or(Qt::black))), + MTP_int(color(theme->outgoingAccentColor.value_or( + Qt::black))), + MTP_vector(colors( + theme->outgoingMessagesColors)), + MTP_inputWallPaperSlug(MTP_string(slug)), + MTP_wallPaperSettings( + MTP_flags(papers), + MTP_int(color(bg[0])), + MTP_int(color(bg.size() > 1 ? bg[1] : Qt::black)), + MTP_int(color(bg.size() > 2 ? bg[2] : Qt::black)), + MTP_int(color(bg.size() > 3 ? bg[3] : Qt::black)), + MTP_int(theme->paper->patternIntensity()), + MTP_int(0))) + )).done([=](const MTPTheme &result) { + const auto slug = Data::CloudTheme::Parse(session, result, true).slug; + QGuiApplication::clipboard()->setText( + session->createInternalLinkFull("addtheme/" + slug)); + Ui::Toast::Show(tr::lng_background_link_copied(tr::now)); + }).fail([=](const MTP::Error &error) { + Ui::Toast::Show("Error: " + error.type()); + }).send(); +} + bool ResolveTestChatTheme( Window::SessionController *controller, const Match &match, @@ -485,6 +580,9 @@ bool ResolveTestChatTheme( history->peer->themeEmoji(), params); if (theme) { + if (!params["export"].isEmpty()) { + ExportTestChatTheme(&controller->session(), &*theme); + } [[maybe_unused]] auto value = controller->cachedChatThemeValue( *theme); } diff --git a/Telegram/SourceFiles/data/data_cloud_themes.cpp b/Telegram/SourceFiles/data/data_cloud_themes.cpp index ea14b8e61..22e803c84 100644 --- a/Telegram/SourceFiles/data/data_cloud_themes.cpp +++ b/Telegram/SourceFiles/data/data_cloud_themes.cpp @@ -433,7 +433,7 @@ void CloudThemes::SetTestingColors(bool testing) { IsTestingColors = testing; } -QString CloudThemes::PrepareTestingLink(const CloudTheme &theme) { +QString CloudThemes::prepareTestingLink(const CloudTheme &theme) const { const auto hex = [](int value) { return QChar((value < 10) ? ('0' + value) : ('a' + (value - 10))); }; @@ -460,6 +460,16 @@ QString CloudThemes::PrepareTestingLink(const CloudTheme &theme) { if (theme.paper && !theme.paper->backgroundColors().empty()) { arguments.push_back("bg=" + colors(theme.paper->backgroundColors())); } + if (theme.paper/* && theme.paper->hasShareUrl()*/) { + arguments.push_back("intensity=" + + QString::number(theme.paper->patternIntensity())); + //const auto url = theme.paper->shareUrl(_session); + //const auto from = url.indexOf("bg/"); + //const auto till = url.indexOf("?"); + //if (from > 0 && till > from) { + // arguments.push_back("slug=" + url.mid(from + 3, till - from - 3)); + //} + } if (theme.outgoingAccentColor) { arguments.push_back("out_accent" + color(*theme.outgoingAccentColor)); } @@ -525,7 +535,11 @@ std::optional CloudThemes::updateThemeFromLink( const auto bg = colors(params["bg"]); applyTo.paper = (applyTo.paper && !bg.empty()) ? std::make_optional(applyTo.paper->withBackgroundColors(bg)) - : std::nullopt; + : applyTo.paper; + applyTo.paper = (applyTo.paper && params["intensity"].toInt()) + ? std::make_optional( + applyTo.paper->withPatternIntensity(params["intensity"].toInt())) + : applyTo.paper; applyTo.outgoingAccentColor = color(params["out_accent"]); applyTo.outgoingMessagesColors = colors(params["out_bg"]); _chatThemesUpdates.fire({}); diff --git a/Telegram/SourceFiles/data/data_cloud_themes.h b/Telegram/SourceFiles/data/data_cloud_themes.h index d2657c361..e6a1b3ca9 100644 --- a/Telegram/SourceFiles/data/data_cloud_themes.h +++ b/Telegram/SourceFiles/data/data_cloud_themes.h @@ -77,7 +77,7 @@ public: [[nodiscard]] static bool TestingColors(); static void SetTestingColors(bool testing); - [[nodiscard]] static QString PrepareTestingLink(const CloudTheme &theme); + [[nodiscard]] QString prepareTestingLink(const CloudTheme &theme) const; [[nodiscard]] std::optional updateThemeFromLink( const QString &emoji, const QMap ¶ms); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index c6c919693..714340142 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -688,7 +688,8 @@ HistoryWidget::HistoryWidget( auto text = QStringList(); const auto push = [&](QString label, const auto &theme) { using namespace Data; - const auto l = CloudThemes::PrepareTestingLink(theme); + const auto &themes = _peer->owner().cloudThemes(); + const auto l = themes.prepareTestingLink(theme); if (!l.isEmpty()) { text.push_back(label + ": " + l); } diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp index 452de4568..b02fe7feb 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp @@ -330,26 +330,6 @@ bool CopyColorsToPalette( return true; } -[[nodiscard]] QString GenerateSlug() { - const auto letters = uint8('Z' + 1 - 'A'); - const auto digits = uint8('9' + 1 - '0'); - const auto values = uint8(2 * letters + digits); - - auto result = QString(); - result.reserve(kRandomSlugSize); - for (auto i = 0; i != kRandomSlugSize; ++i) { - const auto value = base::RandomValue() % values; - if (value < letters) { - result.append(char('A' + value)); - } else if (value < 2 * letters) { - result.append(char('a' + (value - letters))); - } else { - result.append(char('0' + (value - 2 * letters))); - } - } - return result; -} - [[nodiscard]] QByteArray PackTheme(const ParsedTheme &parsed) { zlib::FileToWrite zip; @@ -1018,5 +998,25 @@ ParsedTheme ParseTheme( return result(); } +[[nodiscard]] QString GenerateSlug() { + const auto letters = uint8('Z' + 1 - 'A'); + const auto digits = uint8('9' + 1 - '0'); + const auto values = uint8(2 * letters + digits); + + auto result = QString(); + result.reserve(kRandomSlugSize); + for (auto i = 0; i != kRandomSlugSize; ++i) { + const auto value = base::RandomValue() % values; + if (value < letters) { + result.append(char('A' + value)); + } else if (value < 2 * letters) { + result.append(char('a' + (value - letters))); + } else { + result.append(char('0' + (value - 2 * letters))); + } + } + return result; +} + } // namespace Theme } // namespace Window diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor_box.h b/Telegram/SourceFiles/window/themes/window_theme_editor_box.h index 5d526c905..35364b303 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor_box.h +++ b/Telegram/SourceFiles/window/themes/window_theme_editor_box.h @@ -54,5 +54,7 @@ void SaveThemeBox( bool onlyPalette = false, bool parseCurrent = true); +[[nodiscard]] QString GenerateSlug(); + } // namespace Theme } // namespace Window