mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Add a simple way of testing color themes.
This commit is contained in:
parent
c4d822ba02
commit
13c00949ed
7 changed files with 194 additions and 2 deletions
|
@ -39,6 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "mainwidget.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_session_settings.h"
|
||||
#include "history/history.h"
|
||||
#include "apiwrap.h"
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
@ -464,6 +465,29 @@ bool ShowInviteLink(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ResolveTestChatTheme(
|
||||
Window::SessionController *controller,
|
||||
const Match &match,
|
||||
const QVariant &context) {
|
||||
if (!controller) {
|
||||
return false;
|
||||
}
|
||||
const auto params = url_parse_params(
|
||||
match->captured(1),
|
||||
qthelp::UrlParamNameTransform::ToLower);
|
||||
if (const auto history = controller->activeChatCurrent().history()) {
|
||||
controller->clearCachedChatThemes();
|
||||
const auto theme = history->owner().cloudThemes().updateThemeFromLink(
|
||||
history->peer->themeEmoji(),
|
||||
params);
|
||||
if (theme) {
|
||||
[[maybe_unused]] auto value = controller->cachedChatThemeValue(
|
||||
*theme);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
|
||||
|
@ -524,6 +548,10 @@ const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
|
|||
qsl("^settings(/folders|/devices|/language)?$"),
|
||||
ResolveSettings
|
||||
},
|
||||
{
|
||||
qsl("^test_chat_theme/?\\?(.+)(#|$)"),
|
||||
ResolveTestChatTheme,
|
||||
},
|
||||
{
|
||||
qsl("^([^\\?]+)(\\?|#|$)"),
|
||||
HandleUnknown
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace {
|
|||
constexpr auto kFirstReloadTimeout = 10 * crl::time(1000);
|
||||
constexpr auto kReloadTimeout = 3600 * crl::time(1000);
|
||||
|
||||
bool IsTestingColors/* = false*/;
|
||||
|
||||
} // namespace
|
||||
|
||||
CloudTheme CloudTheme::Parse(
|
||||
|
@ -395,12 +397,24 @@ std::optional<ChatTheme> CloudThemes::themeForEmoji(
|
|||
|
||||
rpl::producer<std::optional<ChatTheme>> CloudThemes::themeForEmojiValue(
|
||||
const QString &emoji) {
|
||||
const auto testing = TestingColors();
|
||||
if (emoji.isEmpty()) {
|
||||
return rpl::single<std::optional<ChatTheme>>(std::nullopt);
|
||||
} else if (auto result = themeForEmoji(emoji)) {
|
||||
if (testing) {
|
||||
return rpl::single(
|
||||
std::move(result)
|
||||
) | rpl::then(chatThemesUpdated(
|
||||
) | rpl::map([=] {
|
||||
return themeForEmoji(emoji);
|
||||
}) | rpl::filter([](const std::optional<ChatTheme> &theme) {
|
||||
return theme.has_value();
|
||||
}));
|
||||
}
|
||||
return rpl::single(std::move(result));
|
||||
}
|
||||
refreshChatThemes();
|
||||
const auto limit = testing ? (1 << 20) : 1;
|
||||
return rpl::single<std::optional<ChatTheme>>(
|
||||
std::nullopt
|
||||
) | rpl::then(chatThemesUpdated(
|
||||
|
@ -408,7 +422,112 @@ rpl::producer<std::optional<ChatTheme>> CloudThemes::themeForEmojiValue(
|
|||
return themeForEmoji(emoji);
|
||||
}) | rpl::filter([](const std::optional<ChatTheme> &theme) {
|
||||
return theme.has_value();
|
||||
}) | rpl::take(1));
|
||||
}) | rpl::take(limit));
|
||||
}
|
||||
|
||||
bool CloudThemes::TestingColors() {
|
||||
return IsTestingColors;
|
||||
}
|
||||
|
||||
void CloudThemes::SetTestingColors(bool testing) {
|
||||
IsTestingColors = testing;
|
||||
}
|
||||
|
||||
QString CloudThemes::PrepareTestingLink(const CloudTheme &theme) {
|
||||
const auto hex = [](int value) {
|
||||
return QChar((value < 10) ? ('0' + value) : ('a' + (value - 10)));
|
||||
};
|
||||
const auto hex2 = [&](int value) {
|
||||
return QString() + hex(value / 16) + hex(value % 16);
|
||||
};
|
||||
const auto color = [&](const QColor &color) {
|
||||
return hex2(color.red()) + hex2(color.green()) + hex2(color.blue());
|
||||
};
|
||||
const auto colors = [&](const std::vector<QColor> &colors) {
|
||||
auto list = QStringList();
|
||||
for (const auto &c : colors) {
|
||||
list.push_back(color(c));
|
||||
}
|
||||
return list.join(",");
|
||||
};
|
||||
auto arguments = QStringList();
|
||||
if (theme.basedOnDark) {
|
||||
arguments.push_back("dark=1");
|
||||
}
|
||||
if (theme.accentColor) {
|
||||
arguments.push_back("accent=" + color(*theme.accentColor));
|
||||
}
|
||||
if (theme.paper && !theme.paper->backgroundColors().empty()) {
|
||||
arguments.push_back("bg=" + colors(theme.paper->backgroundColors()));
|
||||
}
|
||||
if (theme.outgoingAccentColor) {
|
||||
arguments.push_back("out_accent" + color(*theme.outgoingAccentColor));
|
||||
}
|
||||
if (!theme.outgoingMessagesColors.empty()) {
|
||||
arguments.push_back("out_bg=" + colors(theme.outgoingMessagesColors));
|
||||
}
|
||||
return arguments.isEmpty()
|
||||
? QString()
|
||||
: ("tg://test_chat_theme?" + arguments.join("&"));
|
||||
}
|
||||
|
||||
std::optional<CloudTheme> CloudThemes::updateThemeFromLink(
|
||||
const QString &emoji,
|
||||
const QMap<QString, QString> ¶ms) {
|
||||
if (!TestingColors()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto i = ranges::find(_chatThemes, emoji, &ChatTheme::emoji);
|
||||
if (i == end(_chatThemes)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto hex = [](const QString &value) {
|
||||
return (value.size() != 1)
|
||||
? std::nullopt
|
||||
: (value[0] >= 'a' && value[0] <= 'f')
|
||||
? std::make_optional(10 + int(value[0].unicode() - 'a'))
|
||||
: (value[0] >= '0' && value[0] <= '9')
|
||||
? std::make_optional(int(value[0].unicode() - '0'))
|
||||
: std::nullopt;
|
||||
};
|
||||
const auto hex2 = [&](const QString &value) {
|
||||
const auto first = hex(value.mid(0, 1));
|
||||
const auto second = hex(value.mid(1, 1));
|
||||
return (first && second)
|
||||
? std::make_optional((*first) * 16 + (*second))
|
||||
: std::nullopt;
|
||||
};
|
||||
const auto color = [&](const QString &value) {
|
||||
const auto red = hex2(value.mid(0, 2));
|
||||
const auto green = hex2(value.mid(2, 2));
|
||||
const auto blue = hex2(value.mid(4, 2));
|
||||
return (red && green && blue)
|
||||
? std::make_optional(QColor(*red, *green, *blue))
|
||||
: std::nullopt;
|
||||
};
|
||||
const auto colors = [&](const QString &value) {
|
||||
auto list = value.split(",");
|
||||
auto result = std::vector<QColor>();
|
||||
for (const auto &single : list) {
|
||||
if (const auto c = color(single)) {
|
||||
result.push_back(*c);
|
||||
} else {
|
||||
return std::vector<QColor>();
|
||||
}
|
||||
}
|
||||
return (result.size() > 4) ? std::vector<QColor>() : result;
|
||||
};
|
||||
|
||||
auto &applyTo = params["dark"].isEmpty() ? i->light : i->dark;
|
||||
applyTo.accentColor = color(params["accent"]);
|
||||
const auto bg = colors(params["bg"]);
|
||||
applyTo.paper = (applyTo.paper && !bg.empty())
|
||||
? std::make_optional(applyTo.paper->withBackgroundColors(bg))
|
||||
: std::nullopt;
|
||||
applyTo.outgoingAccentColor = color(params["out_accent"]);
|
||||
applyTo.outgoingMessagesColors = colors(params["out_bg"]);
|
||||
_chatThemesUpdates.fire({});
|
||||
return applyTo;
|
||||
}
|
||||
|
||||
void CloudThemes::parseChatThemes(const QVector<MTPChatTheme> &list) {
|
||||
|
|
|
@ -75,6 +75,13 @@ public:
|
|||
[[nodiscard]] rpl::producer<std::optional<ChatTheme>> themeForEmojiValue(
|
||||
const QString &emoji);
|
||||
|
||||
[[nodiscard]] static bool TestingColors();
|
||||
[[nodiscard]] static void SetTestingColors(bool testing);
|
||||
[[nodiscard]] static QString PrepareTestingLink(const CloudTheme &theme);
|
||||
[[nodiscard]] std::optional<CloudTheme> updateThemeFromLink(
|
||||
const QString &emoji,
|
||||
const QMap<QString, QString> ¶ms);
|
||||
|
||||
void applyUpdate(const MTPTheme &theme);
|
||||
|
||||
void resolve(
|
||||
|
|
|
@ -632,6 +632,7 @@ HistoryWidget::HistoryWidget(
|
|||
| PeerUpdateFlag::Slowmode
|
||||
| PeerUpdateFlag::BotStartToken
|
||||
| PeerUpdateFlag::MessagesTTL
|
||||
| PeerUpdateFlag::ChatThemeEmoji
|
||||
) | rpl::filter([=](const Data::PeerUpdate &update) {
|
||||
return (update.peer.get() == _peer);
|
||||
}) | rpl::map([](const Data::PeerUpdate &update) {
|
||||
|
@ -675,6 +676,31 @@ HistoryWidget::HistoryWidget(
|
|||
if (flags & PeerUpdateFlag::MessagesTTL) {
|
||||
checkMessagesTTL();
|
||||
}
|
||||
if ((flags & PeerUpdateFlag::ChatThemeEmoji) && _list) {
|
||||
const auto emoji = _peer->themeEmoji();
|
||||
if (Data::CloudThemes::TestingColors() && !emoji.isEmpty()) {
|
||||
_peer->owner().cloudThemes().themeForEmojiValue(
|
||||
emoji
|
||||
) | rpl::filter_optional(
|
||||
) | rpl::take(
|
||||
1
|
||||
) | rpl::start_with_next([=](const Data::ChatTheme &theme) {
|
||||
auto text = QStringList();
|
||||
const auto push = [&](QString label, const auto &theme) {
|
||||
using namespace Data;
|
||||
const auto l = CloudThemes::PrepareTestingLink(theme);
|
||||
if (!l.isEmpty()) {
|
||||
text.push_back(label + ": " + l);
|
||||
}
|
||||
};
|
||||
push("Light", theme.light);
|
||||
push("Dark", theme.dark);
|
||||
if (!text.isEmpty()) {
|
||||
_field->setText(text.join("\n\n"));
|
||||
}
|
||||
}, _list->lifetime());
|
||||
}
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
rpl::merge(
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_cloud_themes.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_account.h"
|
||||
#include "main/main_domain.h"
|
||||
|
@ -274,6 +275,11 @@ auto GenerateCodes() {
|
|||
});
|
||||
});
|
||||
});
|
||||
codes.emplace(qsl("testchatcolors"), [](SessionController *window) {
|
||||
const auto now = !Data::CloudThemes::TestingColors();
|
||||
Data::CloudThemes::SetTestingColors(now);
|
||||
Ui::Toast::Show(now ? "Testing chat theme colors!" : "Not testing..");
|
||||
});
|
||||
|
||||
return codes;
|
||||
}
|
||||
|
|
|
@ -1399,13 +1399,14 @@ auto SessionController::cachedChatThemeValue(
|
|||
if (i == end(_customChatThemes)) {
|
||||
cacheChatTheme(data);
|
||||
}
|
||||
const auto limit = Data::CloudThemes::TestingColors() ? (1 << 20) : 1;
|
||||
using namespace rpl::mappers;
|
||||
return rpl::single(
|
||||
_defaultChatTheme
|
||||
) | rpl::then(_cachedThemesStream.events(
|
||||
) | rpl::filter([=](const std::shared_ptr<Ui::ChatTheme> &theme) {
|
||||
return (theme->key() == key);
|
||||
}) | rpl::take(1));
|
||||
}) | rpl::take(limit));
|
||||
}
|
||||
|
||||
void SessionController::setChatStyleTheme(
|
||||
|
@ -1417,6 +1418,10 @@ void SessionController::setChatStyleTheme(
|
|||
_chatStyle->apply(theme.get());
|
||||
}
|
||||
|
||||
void SessionController::clearCachedChatThemes() {
|
||||
_customChatThemes.clear();
|
||||
}
|
||||
|
||||
void SessionController::pushDefaultChatBackground() {
|
||||
const auto background = Theme::Background();
|
||||
const auto &paper = background->paper();
|
||||
|
|
|
@ -407,6 +407,7 @@ public:
|
|||
const Data::CloudTheme &data)
|
||||
-> rpl::producer<std::shared_ptr<Ui::ChatTheme>>;
|
||||
void setChatStyleTheme(const std::shared_ptr<Ui::ChatTheme> &theme);
|
||||
void clearCachedChatThemes();
|
||||
|
||||
struct PaintContextArgs {
|
||||
not_null<Ui::ChatTheme*> theme;
|
||||
|
|
Loading…
Add table
Reference in a new issue