Allow exporting test chat themes.
This commit is contained in:
parent
8274fddcbc
commit
e0135e509d
6 changed files with 139 additions and 24 deletions
|
@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "media/player/media_player_instance.h"
|
#include "media/player/media_player_instance.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
|
#include "window/themes/window_theme_editor_box.h" // GenerateSlug.
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
@ -469,6 +470,100 @@ bool ShowInviteLink(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExportTestChatTheme(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
not_null<const Data::CloudTheme*> 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<QColor> &colors) {
|
||||||
|
auto result = QVector<MTPint>();
|
||||||
|
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<MTPint>(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(
|
bool ResolveTestChatTheme(
|
||||||
Window::SessionController *controller,
|
Window::SessionController *controller,
|
||||||
const Match &match,
|
const Match &match,
|
||||||
|
@ -485,6 +580,9 @@ bool ResolveTestChatTheme(
|
||||||
history->peer->themeEmoji(),
|
history->peer->themeEmoji(),
|
||||||
params);
|
params);
|
||||||
if (theme) {
|
if (theme) {
|
||||||
|
if (!params["export"].isEmpty()) {
|
||||||
|
ExportTestChatTheme(&controller->session(), &*theme);
|
||||||
|
}
|
||||||
[[maybe_unused]] auto value = controller->cachedChatThemeValue(
|
[[maybe_unused]] auto value = controller->cachedChatThemeValue(
|
||||||
*theme);
|
*theme);
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,7 +433,7 @@ void CloudThemes::SetTestingColors(bool testing) {
|
||||||
IsTestingColors = testing;
|
IsTestingColors = testing;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CloudThemes::PrepareTestingLink(const CloudTheme &theme) {
|
QString CloudThemes::prepareTestingLink(const CloudTheme &theme) const {
|
||||||
const auto hex = [](int value) {
|
const auto hex = [](int value) {
|
||||||
return QChar((value < 10) ? ('0' + value) : ('a' + (value - 10)));
|
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()) {
|
if (theme.paper && !theme.paper->backgroundColors().empty()) {
|
||||||
arguments.push_back("bg=" + colors(theme.paper->backgroundColors()));
|
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) {
|
if (theme.outgoingAccentColor) {
|
||||||
arguments.push_back("out_accent" + color(*theme.outgoingAccentColor));
|
arguments.push_back("out_accent" + color(*theme.outgoingAccentColor));
|
||||||
}
|
}
|
||||||
|
@ -525,7 +535,11 @@ std::optional<CloudTheme> CloudThemes::updateThemeFromLink(
|
||||||
const auto bg = colors(params["bg"]);
|
const auto bg = colors(params["bg"]);
|
||||||
applyTo.paper = (applyTo.paper && !bg.empty())
|
applyTo.paper = (applyTo.paper && !bg.empty())
|
||||||
? std::make_optional(applyTo.paper->withBackgroundColors(bg))
|
? 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.outgoingAccentColor = color(params["out_accent"]);
|
||||||
applyTo.outgoingMessagesColors = colors(params["out_bg"]);
|
applyTo.outgoingMessagesColors = colors(params["out_bg"]);
|
||||||
_chatThemesUpdates.fire({});
|
_chatThemesUpdates.fire({});
|
||||||
|
|
|
@ -77,7 +77,7 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] static bool TestingColors();
|
[[nodiscard]] static bool TestingColors();
|
||||||
static void SetTestingColors(bool testing);
|
static void SetTestingColors(bool testing);
|
||||||
[[nodiscard]] static QString PrepareTestingLink(const CloudTheme &theme);
|
[[nodiscard]] QString prepareTestingLink(const CloudTheme &theme) const;
|
||||||
[[nodiscard]] std::optional<CloudTheme> updateThemeFromLink(
|
[[nodiscard]] std::optional<CloudTheme> updateThemeFromLink(
|
||||||
const QString &emoji,
|
const QString &emoji,
|
||||||
const QMap<QString, QString> ¶ms);
|
const QMap<QString, QString> ¶ms);
|
||||||
|
|
|
@ -688,7 +688,8 @@ HistoryWidget::HistoryWidget(
|
||||||
auto text = QStringList();
|
auto text = QStringList();
|
||||||
const auto push = [&](QString label, const auto &theme) {
|
const auto push = [&](QString label, const auto &theme) {
|
||||||
using namespace Data;
|
using namespace Data;
|
||||||
const auto l = CloudThemes::PrepareTestingLink(theme);
|
const auto &themes = _peer->owner().cloudThemes();
|
||||||
|
const auto l = themes.prepareTestingLink(theme);
|
||||||
if (!l.isEmpty()) {
|
if (!l.isEmpty()) {
|
||||||
text.push_back(label + ": " + l);
|
text.push_back(label + ": " + l);
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,26 +330,6 @@ bool CopyColorsToPalette(
|
||||||
return true;
|
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<uint8>() % 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) {
|
[[nodiscard]] QByteArray PackTheme(const ParsedTheme &parsed) {
|
||||||
zlib::FileToWrite zip;
|
zlib::FileToWrite zip;
|
||||||
|
|
||||||
|
@ -1018,5 +998,25 @@ ParsedTheme ParseTheme(
|
||||||
return result();
|
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<uint8>() % 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 Theme
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
|
@ -54,5 +54,7 @@ void SaveThemeBox(
|
||||||
bool onlyPalette = false,
|
bool onlyPalette = false,
|
||||||
bool parseCurrent = true);
|
bool parseCurrent = true);
|
||||||
|
|
||||||
|
[[nodiscard]] QString GenerateSlug();
|
||||||
|
|
||||||
} // namespace Theme
|
} // namespace Theme
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
Loading…
Reference in a new issue