mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/telegramdesktop/tdesktop
synced 2026-09-20 08:03:45 +08:00
Start gift theme background parsing.
This commit is contained in:
@@ -39,44 +39,38 @@ CloudTheme CloudTheme::Parse(
|
||||
bool parseSettings) {
|
||||
const auto document = data.vdocument();
|
||||
const auto paper = [&](const MTPThemeSettings &settings) {
|
||||
return settings.match([&](const MTPDthemeSettings &data) {
|
||||
return data.vwallpaper()
|
||||
? WallPaper::Create(session, *data.vwallpaper())
|
||||
: std::nullopt;
|
||||
});
|
||||
const auto &data = settings.data();
|
||||
return data.vwallpaper()
|
||||
? WallPaper::Create(session, *data.vwallpaper())
|
||||
: std::nullopt;
|
||||
};
|
||||
const auto outgoingMessagesColors = [&](
|
||||
const MTPThemeSettings &settings) {
|
||||
auto result = std::vector<QColor>();
|
||||
settings.match([&](const MTPDthemeSettings &data) {
|
||||
if (const auto colors = data.vmessage_colors()) {
|
||||
for (const auto &color : colors->v) {
|
||||
result.push_back(Ui::ColorFromSerialized(color));
|
||||
}
|
||||
const auto &data = settings.data();
|
||||
if (const auto colors = data.vmessage_colors()) {
|
||||
for (const auto &color : colors->v) {
|
||||
result.push_back(Ui::ColorFromSerialized(color));
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
const auto accentColor = [&](const MTPThemeSettings &settings) {
|
||||
return settings.match([&](const MTPDthemeSettings &data) {
|
||||
return Ui::ColorFromSerialized(data.vaccent_color());
|
||||
});
|
||||
const auto &data = settings.data();
|
||||
return Ui::ColorFromSerialized(data.vaccent_color());
|
||||
};
|
||||
const auto outgoingAccentColor = [&](const MTPThemeSettings &settings) {
|
||||
return settings.match([&](const MTPDthemeSettings &data) {
|
||||
return Ui::MaybeColorFromSerialized(data.voutbox_accent_color());
|
||||
});
|
||||
const auto &data = settings.data();
|
||||
return Ui::MaybeColorFromSerialized(data.voutbox_accent_color());
|
||||
};
|
||||
const auto basedOnDark = [&](const MTPThemeSettings &settings) {
|
||||
return settings.match([&](const MTPDthemeSettings &data) {
|
||||
return data.vbase_theme().match([](
|
||||
const MTPDbaseThemeNight &) {
|
||||
return true;
|
||||
}, [](const MTPDbaseThemeTinted &) {
|
||||
return true;
|
||||
}, [](const auto &) {
|
||||
return false;
|
||||
});
|
||||
const auto &data = settings.data();
|
||||
return data.vbase_theme().match([](const MTPDbaseThemeNight &) {
|
||||
return true;
|
||||
}, [](const MTPDbaseThemeTinted &) {
|
||||
return true;
|
||||
}, [](const auto &) {
|
||||
return false;
|
||||
});
|
||||
};
|
||||
const auto settings = [&] {
|
||||
@@ -122,45 +116,48 @@ CloudTheme CloudTheme::Parse(
|
||||
return {};
|
||||
}
|
||||
const auto paper = [&](const MTPThemeSettings &settings) {
|
||||
return settings.match([&](const MTPDthemeSettings &data) {
|
||||
return data.vwallpaper()
|
||||
? WallPaper::Create(session, *data.vwallpaper())
|
||||
: std::nullopt;
|
||||
const auto &data = settings.data();
|
||||
return data.vwallpaper()
|
||||
? WallPaper::Create(session, *data.vwallpaper())
|
||||
: std::nullopt;
|
||||
};
|
||||
const auto basedOnDark = [&](const MTPThemeSettings &settings) {
|
||||
const auto &data = settings.data();
|
||||
return data.vbase_theme().match([](const MTPDbaseThemeNight &) {
|
||||
return true;
|
||||
}, [](const MTPDbaseThemeTinted &) {
|
||||
return true;
|
||||
}, [](const auto &) {
|
||||
return false;
|
||||
});
|
||||
};
|
||||
const auto outgoingMessagesColors = [&](
|
||||
const MTPThemeSettings &settings) {
|
||||
auto result = std::vector<QColor>();
|
||||
settings.match([&](const MTPDthemeSettings &data) {
|
||||
if (const auto colors = data.vmessage_colors()) {
|
||||
for (const auto &color : colors->v) {
|
||||
result.push_back(Ui::ColorFromSerialized(color));
|
||||
}
|
||||
const auto &data = settings.data();
|
||||
if (const auto colors = data.vmessage_colors()) {
|
||||
for (const auto &color : colors->v) {
|
||||
result.push_back(Ui::ColorFromSerialized(color));
|
||||
}
|
||||
});
|
||||
//} else if (basedOnDark(settings)) {
|
||||
// result.push_back(gift->unique->backdrop.edgeColor);
|
||||
//} else {
|
||||
// result.push_back(anim::color(
|
||||
// gift->unique->backdrop.patternColor,
|
||||
// QColor(255, 255, 255, 255),
|
||||
// 0.75));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
const auto accentColor = [&](const MTPThemeSettings &settings) {
|
||||
return settings.match([&](const MTPDthemeSettings &data) {
|
||||
return Ui::ColorFromSerialized(data.vaccent_color());
|
||||
});
|
||||
const auto &data = settings.data();
|
||||
return Ui::ColorFromSerialized(data.vaccent_color());
|
||||
};
|
||||
const auto outgoingAccentColor = [&](const MTPThemeSettings &settings) {
|
||||
return settings.match([&](const MTPDthemeSettings &data) {
|
||||
return Ui::MaybeColorFromSerialized(data.voutbox_accent_color());
|
||||
});
|
||||
};
|
||||
const auto basedOnDark = [&](const MTPThemeSettings &settings) {
|
||||
return settings.match([&](const MTPDthemeSettings &data) {
|
||||
return data.vbase_theme().match([](
|
||||
const MTPDbaseThemeNight &) {
|
||||
return true;
|
||||
}, [](const MTPDbaseThemeTinted &) {
|
||||
return true;
|
||||
}, [](const auto &) {
|
||||
return false;
|
||||
});
|
||||
});
|
||||
const auto &data = settings.data();
|
||||
return Ui::MaybeColorFromSerialized(
|
||||
data.voutbox_accent_color()
|
||||
);// .value_or(gift->unique->backdrop.patternColor);
|
||||
};
|
||||
const auto settings = [&] {
|
||||
auto result = base::flat_map<Type, Settings>();
|
||||
@@ -538,7 +535,7 @@ void CloudThemes::myGiftThemesLoadMore(bool reload) {
|
||||
});
|
||||
}
|
||||
_myGiftThemesLoaded = (got < kGiftThemesLimit);
|
||||
_chatThemesUpdates.fire({});
|
||||
_myGiftThemesUpdates.fire({});
|
||||
}, [&](const MTPDaccount_chatThemesNotModified &) {
|
||||
if (!reload) {
|
||||
_myGiftThemesLoaded = true;
|
||||
|
||||
@@ -653,7 +653,11 @@ bool DocumentData::checkWallPaperProperties() {
|
||||
if (type == WallPaperDocument) {
|
||||
return true;
|
||||
}
|
||||
if (type != FileDocument
|
||||
if (hasMimeType(u"application/x-tgwallpattern"_q)
|
||||
&& dimensions.isEmpty()) {
|
||||
dimensions = QSize(1125, 2313);
|
||||
AssertIsDebug();
|
||||
} else if (type != FileDocument
|
||||
|| !hasThumbnail()
|
||||
|| dimensions.isEmpty()
|
||||
|| dimensions.width() > Storage::kMaxWallPaperDimension
|
||||
|
||||
@@ -169,7 +169,7 @@ base::binary_guard ReadBackgroundImageAsync(
|
||||
guard = result.make_guard(),
|
||||
callback = std::move(done)
|
||||
]() mutable {
|
||||
auto image = Ui::ReadBackgroundImage(path, bytes, gzipSvg);
|
||||
auto image = Ui::ReadBackgroundImage(path, bytes, gzipSvg).image;
|
||||
if (postprocess) {
|
||||
image = postprocess(std::move(image));
|
||||
}
|
||||
|
||||
@@ -1739,7 +1739,8 @@ PeerId PeerData::groupCallDefaultJoinAs() const {
|
||||
void PeerData::setThemeToken(const QString &token) {
|
||||
if (_themeToken == token) {
|
||||
return;
|
||||
} else if (Ui::Emoji::Find(_themeToken) == Ui::Emoji::Find(token)) {
|
||||
} else if (!token.startsWith(u"gift:"_q)
|
||||
&& Ui::Emoji::Find(_themeToken) == Ui::Emoji::Find(token)) {
|
||||
_themeToken = token;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -415,6 +415,7 @@ void ChatTheme::setBackground(ChatThemeBackground &&background) {
|
||||
void ChatTheme::updateBackgroundImageFrom(ChatThemeBackground &&background) {
|
||||
_mutableBackground.key = background.key;
|
||||
_mutableBackground.prepared = std::move(background.prepared);
|
||||
_mutableBackground.giftSymbols = std::move(background.giftSymbols);
|
||||
_mutableBackground.preparedForTiled = std::move(
|
||||
background.preparedForTiled);
|
||||
if (!_backgroundState.now.pixmap.isNull()) {
|
||||
@@ -905,19 +906,83 @@ QImage PrepareImageForTiled(const QImage &prepared) {
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] QImage ReadBackgroundImage(
|
||||
std::vector<QRectF> ParseGiftSymbols(
|
||||
const QByteArray &rects,
|
||||
QSize size,
|
||||
float64 scale) {
|
||||
if (size.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto result = std::vector<QRectF>();
|
||||
auto offset = 0;
|
||||
const auto jumpPast = [&](const QByteArray &what) {
|
||||
const auto pos = rects.indexOf(what, offset);
|
||||
if (pos < 0) {
|
||||
return false;
|
||||
}
|
||||
offset = pos + what.size();
|
||||
return true;
|
||||
};
|
||||
const auto takeDouble = [&](float64 &value) {
|
||||
const auto end = rects.indexOf('"', offset);
|
||||
if (end < 0) {
|
||||
return false;
|
||||
}
|
||||
value = rects.mid(offset, end - offset).toDouble();
|
||||
offset = end + 1;
|
||||
return true;
|
||||
};
|
||||
const auto cw = scale / float64(size.width());
|
||||
const auto ch = scale / float64(size.height());
|
||||
while (true) {
|
||||
auto x = float64(), y = float64(), w = float64(), h = float64();
|
||||
if (!jumpPast("<rect "_q)
|
||||
|| !jumpPast("x=\""_q)
|
||||
|| !takeDouble(x)
|
||||
|| !jumpPast("y=\""_q)
|
||||
|| !takeDouble(y)
|
||||
|| !jumpPast("width=\""_q)
|
||||
|| !takeDouble(w)
|
||||
|| !jumpPast("height=\""_q)
|
||||
|| !takeDouble(h)
|
||||
|| !jumpPast("/>"_q)) {
|
||||
break;
|
||||
}
|
||||
result.push_back({
|
||||
x * cw,
|
||||
y * ch,
|
||||
w * cw,
|
||||
h * ch,
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
BackgroundImageFields ReadBackgroundImage(
|
||||
const QString &path,
|
||||
const QByteArray &content,
|
||||
bool gzipSvg) {
|
||||
auto result = Images::Read({
|
||||
bool gzipSvg,
|
||||
bool findGiftSymbols) {
|
||||
auto read = Images::Read({
|
||||
.path = path,
|
||||
.content = content,
|
||||
.svgCutOutId = findGiftSymbols ? "GiftPatterns"_q : QByteArray(),
|
||||
.maxSize = QSize(kMaxSize, kMaxSize),
|
||||
.gzipSvg = gzipSvg,
|
||||
}).image;
|
||||
if (result.isNull()) {
|
||||
result = QImage(1, 1, QImage::Format_ARGB32_Premultiplied);
|
||||
result.fill(Qt::black);
|
||||
});
|
||||
if (read.image.isNull()) {
|
||||
read.image = QImage(1, 1, QImage::Format_ARGB32_Premultiplied);
|
||||
read.image.fill(Qt::black);
|
||||
}
|
||||
auto result = BackgroundImageFields{
|
||||
.image = std::move(read.image),
|
||||
};
|
||||
if (const auto &rects = read.svgCutOutContent; !rects.isEmpty()) {
|
||||
result.giftSymbols = ParseGiftSymbols(
|
||||
rects,
|
||||
result.image.size(),
|
||||
read.scale);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1022,9 +1087,16 @@ QImage GenerateDitheredGradient(
|
||||
|
||||
ChatThemeBackground PrepareBackgroundImage(
|
||||
const ChatThemeBackgroundData &data) {
|
||||
auto prepared = (data.isPattern || data.colors.empty())
|
||||
? PreprocessBackgroundImage(
|
||||
ReadBackgroundImage(data.path, data.bytes, data.gzipSvg))
|
||||
const auto needBackground = (data.isPattern || data.colors.empty());
|
||||
auto read = needBackground
|
||||
? ReadBackgroundImage(
|
||||
data.path,
|
||||
data.bytes,
|
||||
data.gzipSvg,
|
||||
data.findGiftSymbols)
|
||||
: BackgroundImageFields();
|
||||
auto prepared = needBackground
|
||||
? PreprocessBackgroundImage(std::move(read.image))
|
||||
: QImage();
|
||||
if (data.isPattern && !prepared.isNull()) {
|
||||
if (data.colors.size() < 2) {
|
||||
@@ -1070,6 +1142,7 @@ ChatThemeBackground PrepareBackgroundImage(
|
||||
? std::nullopt
|
||||
: std::make_optional(data.colors.front())),
|
||||
.colors = data.colors,
|
||||
.giftSymbols = std::move(read.giftSymbols),
|
||||
.patternOpacity = data.patternOpacity,
|
||||
.gradientRotation = data.generateGradient ? data.gradientRotation : 0,
|
||||
.isPattern = data.isPattern,
|
||||
|
||||
@@ -29,6 +29,7 @@ struct ChatThemeBackground {
|
||||
QImage gradientForFill;
|
||||
std::optional<QColor> colorForFill;
|
||||
std::vector<QColor> colors;
|
||||
std::vector<QRectF> giftSymbols;
|
||||
float64 patternOpacity = 1.;
|
||||
int gradientRotation = 0;
|
||||
bool isPattern = false;
|
||||
@@ -54,6 +55,7 @@ struct ChatThemeBackgroundData {
|
||||
bool isBlurred = false;
|
||||
bool forDarkMode = false;
|
||||
bool generateGradient = false;
|
||||
bool findGiftSymbols = false;
|
||||
int gradientRotation = 0;
|
||||
};
|
||||
|
||||
@@ -238,10 +240,15 @@ struct ChatBackgroundRects {
|
||||
const QImage &image);
|
||||
[[nodiscard]] QImage PrepareImageForTiled(const QImage &prepared);
|
||||
|
||||
[[nodiscard]] QImage ReadBackgroundImage(
|
||||
struct BackgroundImageFields {
|
||||
QImage image;
|
||||
std::vector<QRectF> giftSymbols;
|
||||
};
|
||||
[[nodiscard]] BackgroundImageFields ReadBackgroundImage(
|
||||
const QString &path,
|
||||
const QByteArray &content,
|
||||
bool gzipSvg);
|
||||
bool gzipSvg,
|
||||
bool findGiftSymbols = false);
|
||||
[[nodiscard]] QImage GenerateBackgroundImage(
|
||||
QSize size,
|
||||
const std::vector<QColor> &bg,
|
||||
|
||||
@@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "main/main_session.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_cloud_themes.h"
|
||||
@@ -146,10 +147,12 @@ const auto kDisableElement = [] { return u"disable"_q; };
|
||||
} // namespace
|
||||
|
||||
struct ChooseThemeController::Entry {
|
||||
QString token;
|
||||
Ui::ChatThemeKey key;
|
||||
std::shared_ptr<Ui::ChatTheme> theme;
|
||||
std::shared_ptr<Data::DocumentMedia> media;
|
||||
std::shared_ptr<Data::UniqueGift> gift;
|
||||
std::unique_ptr<Ui::Text::CustomEmoji> custom;
|
||||
EmojiPtr emoji = nullptr;
|
||||
QImage preview;
|
||||
QRect geometry;
|
||||
@@ -341,14 +344,22 @@ void ChooseThemeController::paintEntry(QPainter &p, const Entry &entry) {
|
||||
|
||||
const auto size = Ui::Emoji::GetSizeLarge();
|
||||
const auto factor = style::DevicePixelRatio();
|
||||
const auto emojiLeft = geometry.x()
|
||||
+ (geometry.width() - (size / factor)) / 2;
|
||||
const auto esize = size / factor;
|
||||
const auto emojiLeft = geometry.x() + (geometry.width() - esize) / 2;
|
||||
const auto emojiTop = geometry.y()
|
||||
+ geometry.height()
|
||||
- (size / factor)
|
||||
- esize
|
||||
- st::chatThemeEmojiBottom;
|
||||
const auto customSize = Ui::Text::AdjustCustomEmojiSize(esize);
|
||||
const auto customSkip = (esize - customSize) / 2;
|
||||
|
||||
if (const auto emoji = entry.emoji) {
|
||||
Ui::Emoji::Draw(p, emoji, size, emojiLeft, emojiTop);
|
||||
} else if (const auto custom = entry.custom.get()) {
|
||||
custom->paint(p, {
|
||||
.textColor = st::windowFg->c,
|
||||
.position = { emojiLeft + customSkip, emojiTop + customSkip },
|
||||
});
|
||||
}
|
||||
|
||||
if (entry.chosen) {
|
||||
@@ -395,7 +406,7 @@ void ChooseThemeController::initList() {
|
||||
if (!entry) {
|
||||
return QString();
|
||||
} else if (entry->key) {
|
||||
return entry->emoji->text();
|
||||
return entry->token;
|
||||
} else {
|
||||
return kDisableElement();
|
||||
}
|
||||
@@ -445,7 +456,7 @@ void ChooseThemeController::initList() {
|
||||
_controller->overridePeerTheme(
|
||||
_peer,
|
||||
entry->theme,
|
||||
entry->emoji);
|
||||
entry->token);
|
||||
}
|
||||
_inner->update();
|
||||
}
|
||||
@@ -508,7 +519,7 @@ void ChooseThemeController::updateInnerLeft(int now) {
|
||||
|
||||
void ChooseThemeController::close() {
|
||||
if (const auto chosen = findChosen()) {
|
||||
if (Ui::Emoji::Find(_peer->themeToken()) != chosen->emoji) {
|
||||
if (_peer->themeToken() != chosen->token) {
|
||||
clearCurrentBackgroundState();
|
||||
}
|
||||
}
|
||||
@@ -531,7 +542,7 @@ auto ChooseThemeController::findChosen() -> Entry* {
|
||||
for (auto &entry : _entries) {
|
||||
if (!entry.key && chosen == kDisableElement()) {
|
||||
return &entry;
|
||||
} else if (chosen == entry.emoji->text()) {
|
||||
} else if (chosen == entry.token) {
|
||||
return &entry;
|
||||
}
|
||||
}
|
||||
@@ -547,18 +558,9 @@ void ChooseThemeController::fill(
|
||||
if (themes.empty()) {
|
||||
return;
|
||||
}
|
||||
const auto count = int(themes.size()) + 1;
|
||||
const auto single = st::chatThemePreviewSize;
|
||||
const auto skip = st::chatThemeEntrySkip;
|
||||
const auto &margin = st::chatThemeEntryMargin;
|
||||
const auto full = margin.left()
|
||||
+ single.width() * count
|
||||
+ skip * (count - 1)
|
||||
+ margin.right();
|
||||
_inner->resize(
|
||||
full,
|
||||
margin.top() + single.height() + margin.bottom());
|
||||
|
||||
const auto initial = Ui::Emoji::Find(_peer->themeToken());
|
||||
if (!initial) {
|
||||
_chosen = kDisableElement();
|
||||
@@ -601,9 +603,11 @@ void ChooseThemeController::fill(
|
||||
if (!emoji || !theme.settings.contains(type)) {
|
||||
continue;
|
||||
}
|
||||
const auto token = emoji->text();
|
||||
const auto key = ChatThemeKey{ theme.id, dark };
|
||||
const auto isChosen = (_chosen.current() == emoji->text());
|
||||
const auto isChosen = (_chosen.current() == token);
|
||||
_entries.push_back({
|
||||
.token = token,
|
||||
.key = key,
|
||||
.emoji = emoji,
|
||||
.geometry = QRect(QPoint(x, skip), single),
|
||||
@@ -624,13 +628,11 @@ void ChooseThemeController::fill(
|
||||
return;
|
||||
}
|
||||
const auto theme = data.get();
|
||||
const auto token = i->token;
|
||||
i->theme = std::move(data);
|
||||
i->preview = GeneratePreview(theme);
|
||||
if (_chosen.current() == i->emoji->text()) {
|
||||
_controller->overridePeerTheme(
|
||||
_peer,
|
||||
i->theme,
|
||||
i->emoji);
|
||||
if (_chosen.current() == token) {
|
||||
_controller->overridePeerTheme(_peer, i->theme, token);
|
||||
}
|
||||
_inner->update();
|
||||
|
||||
@@ -661,17 +663,24 @@ void ChooseThemeController::fill(
|
||||
}, _cachingLifetime);
|
||||
x += single.width() + skip;
|
||||
}
|
||||
const auto owner = &_controller->session().data();
|
||||
const auto manager = &owner->customEmojiManager();
|
||||
for (const auto &token : cloudThemes->myGiftThemesTokens()) {
|
||||
const auto found = cloudThemes->themeForToken(token);
|
||||
if (!found || found->settings.contains(type)) {
|
||||
if (!found || !found->settings.contains(type)) {
|
||||
continue;
|
||||
}
|
||||
const auto &theme = *found;
|
||||
const auto key = ChatThemeKey{ theme.id, dark };
|
||||
const auto isChosen = (_chosen.current() == token);
|
||||
_entries.push_back({
|
||||
.token = token,
|
||||
.key = key,
|
||||
.gift = found->unique,
|
||||
.custom = manager->create(
|
||||
found->unique->model.document,
|
||||
[=] { _inner->update(); },
|
||||
Data::CustomEmojiSizeTag::Large),
|
||||
.geometry = QRect(QPoint(x, skip), single),
|
||||
.chosen = isChosen,
|
||||
});
|
||||
@@ -690,13 +699,11 @@ void ChooseThemeController::fill(
|
||||
return;
|
||||
}
|
||||
const auto theme = data.get();
|
||||
const auto token = i->token;
|
||||
i->theme = std::move(data);
|
||||
i->preview = GeneratePreview(theme);
|
||||
if (_chosen.current() == i->emoji->text()) {
|
||||
_controller->overridePeerTheme(
|
||||
_peer,
|
||||
i->theme,
|
||||
i->emoji);
|
||||
if (_chosen.current() == token) {
|
||||
_controller->overridePeerTheme(_peer, i->theme, token);
|
||||
}
|
||||
_inner->update();
|
||||
|
||||
@@ -728,6 +735,11 @@ void ChooseThemeController::fill(
|
||||
x += single.width() + skip;
|
||||
}
|
||||
|
||||
const auto full = x - skip + margin.right();
|
||||
_inner->resize(
|
||||
full,
|
||||
margin.top() + single.height() + margin.bottom());
|
||||
|
||||
if (!_initialInnerLeftApplied && _content->width() > 0) {
|
||||
applyInitialInnerLeft();
|
||||
}
|
||||
|
||||
@@ -507,7 +507,7 @@ auto ChatThemeValueFromPeer(
|
||||
std::shared_ptr<Ui::ChatTheme> &&cloud,
|
||||
PeerThemeOverride &&overriden) {
|
||||
return (overriden.peer == peer.get()
|
||||
&& Ui::Emoji::Find(peer->themeToken()) != overriden.emoji)
|
||||
&& peer->themeToken() != overriden.token)
|
||||
? std::move(overriden.theme)
|
||||
: std::move(cloud);
|
||||
});
|
||||
|
||||
@@ -74,7 +74,8 @@ inline bool AreTestingTheme() {
|
||||
return Ui::ReadBackgroundImage(
|
||||
u":/gui/art/background.tgv"_q,
|
||||
QByteArray(),
|
||||
true);
|
||||
true
|
||||
).image;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool GoodImageFormatAndSize(const QImage &image) {
|
||||
|
||||
@@ -468,7 +468,8 @@ void Generator::paintHistoryBackground() {
|
||||
background = Ui::ReadBackgroundImage(
|
||||
u":/gui/art/background.tgv"_q,
|
||||
QByteArray(),
|
||||
true);
|
||||
true
|
||||
).image;
|
||||
const auto paper = Data::DefaultWallPaper();
|
||||
background = Ui::PreparePatternImage(
|
||||
std::move(background),
|
||||
|
||||
@@ -1506,6 +1506,7 @@ struct SessionController::CachedTheme {
|
||||
std::weak_ptr<Ui::ChatTheme> theme;
|
||||
std::shared_ptr<Data::DocumentMedia> media;
|
||||
Data::WallPaper paper;
|
||||
bool findGiftSymbols = false;
|
||||
bool basedOnDark = false;
|
||||
bool caching = false;
|
||||
rpl::lifetime lifetime;
|
||||
@@ -3248,11 +3249,11 @@ void SessionController::clearCachedChatThemes() {
|
||||
void SessionController::overridePeerTheme(
|
||||
not_null<PeerData*> peer,
|
||||
std::shared_ptr<Ui::ChatTheme> theme,
|
||||
EmojiPtr emoji) {
|
||||
QString token) {
|
||||
_peerThemeOverride = PeerThemeOverride{
|
||||
peer,
|
||||
theme ? theme : _defaultChatTheme,
|
||||
emoji,
|
||||
token,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3294,12 +3295,14 @@ void SessionController::cacheChatTheme(
|
||||
const auto &use = !paper.isNull() ? paper : *i->second.paper;
|
||||
const auto document = use.document();
|
||||
const auto media = document ? document->createMediaView() : nullptr;
|
||||
const auto findGiftSymbols = (data.unique != nullptr);
|
||||
use.loadDocument();
|
||||
auto &theme = [&]() -> CachedTheme& {
|
||||
const auto i = _customChatThemes.find(key);
|
||||
if (i != end(_customChatThemes)) {
|
||||
i->second.media = media;
|
||||
i->second.paper = use;
|
||||
i->second.findGiftSymbols = findGiftSymbols;
|
||||
i->second.basedOnDark = dark;
|
||||
i->second.caching = true;
|
||||
return i->second;
|
||||
@@ -3309,6 +3312,7 @@ void SessionController::cacheChatTheme(
|
||||
CachedTheme{
|
||||
.media = media,
|
||||
.paper = use,
|
||||
.findGiftSymbols = findGiftSymbols,
|
||||
.basedOnDark = dark,
|
||||
.caching = true,
|
||||
}).first->second;
|
||||
@@ -3428,6 +3432,7 @@ Ui::ChatThemeBackgroundData SessionController::backgroundData(
|
||||
.isBlurred = isBlurred,
|
||||
.forDarkMode = theme.basedOnDark,
|
||||
.generateGradient = generateGradient,
|
||||
.findGiftSymbols = theme.findGiftSymbols,
|
||||
.gradientRotation = gradientRotation,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ struct SeparateId;
|
||||
struct PeerThemeOverride {
|
||||
PeerData *peer = nullptr;
|
||||
std::shared_ptr<Ui::ChatTheme> theme;
|
||||
EmojiPtr emoji = nullptr;
|
||||
QString token;
|
||||
};
|
||||
bool operator==(const PeerThemeOverride &a, const PeerThemeOverride &b);
|
||||
bool operator!=(const PeerThemeOverride &a, const PeerThemeOverride &b);
|
||||
@@ -642,7 +642,7 @@ public:
|
||||
void overridePeerTheme(
|
||||
not_null<PeerData*> peer,
|
||||
std::shared_ptr<Ui::ChatTheme> theme,
|
||||
EmojiPtr emoji);
|
||||
QString token);
|
||||
void clearPeerThemeOverride(not_null<PeerData*> peer);
|
||||
[[nodiscard]] auto peerThemeOverrideValue() const
|
||||
-> rpl::producer<PeerThemeOverride> {
|
||||
|
||||
Submodule Telegram/lib_ui updated: 962581d1bf...c9c1f63df8
Reference in New Issue
Block a user