mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Generate previews async in cloud themes list.
This commit is contained in:
parent
048658f838
commit
eebcdb842d
7 changed files with 100 additions and 56 deletions
|
@ -272,6 +272,18 @@ void CloudThemes::parseThemes(const QVector<MTPTheme> &list) {
|
||||||
LOG(("API Error: Unexpected themeDocumentNotModified."));
|
LOG(("API Error: Unexpected themeDocumentNotModified."));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
checkCurrentTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloudThemes::checkCurrentTheme() {
|
||||||
|
const auto &object = Window::Theme::Background()->themeObject();
|
||||||
|
if (!object.cloud.id || !object.cloud.documentId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto i = ranges::find(_list, object.cloud.id, &CloudTheme::id);
|
||||||
|
if (i == end(_list)) {
|
||||||
|
install();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> CloudThemes::updated() const {
|
rpl::producer<> CloudThemes::updated() const {
|
||||||
|
|
|
@ -56,6 +56,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void parseThemes(const QVector<MTPTheme> &list);
|
void parseThemes(const QVector<MTPTheme> &list);
|
||||||
|
void checkCurrentTheme();
|
||||||
|
|
||||||
void install();
|
void install();
|
||||||
void setupReload();
|
void setupReload();
|
||||||
|
|
|
@ -259,13 +259,20 @@ bool loadBackground(zlib::FileToRead &file, QByteArray *outBackground, bool *out
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool loadTheme(
|
bool LoadTheme(
|
||||||
const QByteArray &content,
|
const QByteArray &content,
|
||||||
const std::optional<QByteArray> &editedPalette,
|
|
||||||
Cached &cache,
|
|
||||||
const Colorizer &colorizer,
|
const Colorizer &colorizer,
|
||||||
|
const std::optional<QByteArray> &editedPalette,
|
||||||
|
Cached *cache = nullptr,
|
||||||
Instance *out = nullptr) {
|
Instance *out = nullptr) {
|
||||||
cache = Cached();
|
if (content.size() < 4) {
|
||||||
|
LOG(("Theme Error: Bad theme content size: %1").arg(content.size()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache) {
|
||||||
|
*cache = Cached();
|
||||||
|
}
|
||||||
zlib::FileToRead file(content);
|
zlib::FileToRead file(content);
|
||||||
|
|
||||||
const auto emptyColorizer = Colorizer();
|
const auto emptyColorizer = Colorizer();
|
||||||
|
@ -289,7 +296,9 @@ bool loadTheme(
|
||||||
if (!loadColorScheme(schemeContent, paletteColorizer, out)) {
|
if (!loadColorScheme(schemeContent, paletteColorizer, out)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!out) {
|
||||||
Background()->saveAdjustableColors();
|
Background()->saveAdjustableColors();
|
||||||
|
}
|
||||||
|
|
||||||
auto backgroundTiled = false;
|
auto backgroundTiled = false;
|
||||||
auto backgroundContent = QByteArray();
|
auto backgroundContent = QByteArray();
|
||||||
|
@ -314,30 +323,37 @@ bool loadTheme(
|
||||||
if (colorizer) {
|
if (colorizer) {
|
||||||
Colorize(background, colorizer);
|
Colorize(background, colorizer);
|
||||||
}
|
}
|
||||||
auto buffer = QBuffer(&cache.background);
|
if (cache) {
|
||||||
|
auto buffer = QBuffer(&cache->background);
|
||||||
if (!background.save(&buffer, "BMP")) {
|
if (!background.save(&buffer, "BMP")) {
|
||||||
LOG(("Theme Error: could not write background image as a BMP to cache."));
|
LOG(("Theme Error: could not write background image as a BMP to cache."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cache.tiled = backgroundTiled;
|
cache->tiled = backgroundTiled;
|
||||||
|
}
|
||||||
applyBackground(std::move(background), cache.tiled, out);
|
applyBackground(std::move(background), backgroundTiled, out);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Looks like it is not a .zip theme.
|
// Looks like it is not a .zip theme.
|
||||||
if (!loadColorScheme(editedPalette.value_or(content), paletteColorizer, out)) {
|
if (!loadColorScheme(editedPalette.value_or(content), paletteColorizer, out)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!out) {
|
||||||
Background()->saveAdjustableColors();
|
Background()->saveAdjustableColors();
|
||||||
}
|
}
|
||||||
if (out) {
|
|
||||||
cache.colors = out->palette.save();
|
|
||||||
} else {
|
|
||||||
cache.colors = style::main_palette::save();
|
|
||||||
}
|
}
|
||||||
cache.paletteChecksum = style::palette::Checksum();
|
if (out) {
|
||||||
cache.contentChecksum = hashCrc32(content.constData(), content.size());
|
out->palette.finalize();
|
||||||
|
}
|
||||||
|
if (cache) {
|
||||||
|
if (out) {
|
||||||
|
cache->colors = out->palette.save();
|
||||||
|
} else {
|
||||||
|
cache->colors = style::main_palette::save();
|
||||||
|
}
|
||||||
|
cache->paletteChecksum = style::palette::Checksum();
|
||||||
|
cache->contentChecksum = hashCrc32(content.constData(), content.size());
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +412,7 @@ bool InitializeFromSaved(Saved &&saved) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto colorizer = ColorizerForTheme(saved.object.pathAbsolute);
|
const auto colorizer = ColorizerForTheme(saved.object.pathAbsolute);
|
||||||
if (!loadTheme(saved.object.content, editing, saved.cache, colorizer)) {
|
if (!LoadTheme(saved.object.content, colorizer, editing, &saved.cache)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (editing) {
|
if (editing) {
|
||||||
|
@ -1046,11 +1062,11 @@ void ChatBackground::reapplyWithNightMode(
|
||||||
auto preview = std::make_unique<Preview>();
|
auto preview = std::make_unique<Preview>();
|
||||||
preview->object = std::move(read.object);
|
preview->object = std::move(read.object);
|
||||||
preview->instance.cached = std::move(read.cache);
|
preview->instance.cached = std::move(read.cache);
|
||||||
const auto loaded = loadTheme(
|
const auto loaded = LoadTheme(
|
||||||
preview->object.content,
|
preview->object.content,
|
||||||
std::nullopt,
|
|
||||||
preview->instance.cached,
|
|
||||||
ColorizerForTheme(path),
|
ColorizerForTheme(path),
|
||||||
|
std::nullopt,
|
||||||
|
&preview->instance.cached,
|
||||||
&preview->instance);
|
&preview->instance);
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1252,28 +1268,21 @@ void ResetToSomeDefault() {
|
||||||
IsNightMode());
|
IsNightMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadFromContent(
|
|
||||||
const QByteArray &content,
|
|
||||||
not_null<Instance*> out,
|
|
||||||
const Colorizer &colorizer) {
|
|
||||||
if (content.size() < 4) {
|
|
||||||
LOG(("Theme Error: Bad theme content size: %1").arg(content.size()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return loadTheme(content, std::nullopt, out->cached, colorizer, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LoadFromFile(
|
bool LoadFromFile(
|
||||||
const QString &path,
|
const QString &path,
|
||||||
not_null<Instance*> out,
|
not_null<Instance*> out,
|
||||||
|
Cached *outCache,
|
||||||
not_null<QByteArray*> outContent) {
|
not_null<QByteArray*> outContent) {
|
||||||
*outContent = readThemeContent(path);
|
*outContent = readThemeContent(path);
|
||||||
return LoadFromContent(*outContent, out, ColorizerForTheme(path));
|
const auto colorizer = ColorizerForTheme(path);
|
||||||
|
return LoadTheme(*outContent, colorizer, std::nullopt, outCache, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadFromContent(const QByteArray &content, not_null<Instance*> out) {
|
bool LoadFromContent(
|
||||||
return LoadFromContent(content, out, {});
|
const QByteArray &content,
|
||||||
|
not_null<Instance*> out,
|
||||||
|
Cached *outCache) {
|
||||||
|
return LoadTheme(content, Colorizer(), std::nullopt, outCache, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString EditingPalettePath() {
|
QString EditingPalettePath() {
|
||||||
|
|
|
@ -84,8 +84,12 @@ void Revert();
|
||||||
bool LoadFromFile(
|
bool LoadFromFile(
|
||||||
const QString &file,
|
const QString &file,
|
||||||
not_null<Instance*> out,
|
not_null<Instance*> out,
|
||||||
|
Cached *outCache,
|
||||||
not_null<QByteArray*> outContent);
|
not_null<QByteArray*> outContent);
|
||||||
bool LoadFromContent(const QByteArray &content, not_null<Instance*> out);
|
bool LoadFromContent(
|
||||||
|
const QByteArray &content,
|
||||||
|
not_null<Instance*> out,
|
||||||
|
Cached *outCache);
|
||||||
QColor CountAverageColor(const QImage &image);
|
QColor CountAverageColor(const QImage &image);
|
||||||
QColor AdjustedColor(QColor original, QColor background);
|
QColor AdjustedColor(QColor original, QColor background);
|
||||||
QImage ProcessBackgroundImage(QImage image);
|
QImage ProcessBackgroundImage(QImage image);
|
||||||
|
|
|
@ -925,13 +925,15 @@ std::unique_ptr<Preview> PreviewFromFile(
|
||||||
object.pathRelative = filepath.isEmpty()
|
object.pathRelative = filepath.isEmpty()
|
||||||
? object.pathAbsolute
|
? object.pathAbsolute
|
||||||
: QDir().relativeFilePath(filepath);
|
: QDir().relativeFilePath(filepath);
|
||||||
|
const auto instance = &result->instance;
|
||||||
|
const auto cache = &result->instance.cached;
|
||||||
if (bytes.isEmpty()) {
|
if (bytes.isEmpty()) {
|
||||||
if (!LoadFromFile(filepath, &result->instance, &object.content)) {
|
if (!LoadFromFile(filepath, instance, cache, &object.content)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
object.content = bytes;
|
object.content = bytes;
|
||||||
if (!LoadFromContent(bytes, &result->instance)) {
|
if (!LoadFromContent(bytes, instance, cache)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ constexpr auto kShowPerRow = 4;
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
auto instance = Instance();
|
auto instance = Instance();
|
||||||
if (!LoadFromContent(content, &instance)) {
|
if (!LoadFromContent(content, &instance, nullptr)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
auto result = CloudListColors();
|
auto result = CloudListColors();
|
||||||
|
@ -519,10 +519,16 @@ void CloudList::refreshElementUsing(
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloudList::refreshColors(Element &element) {
|
void CloudList::refreshColors(Element &element) {
|
||||||
if (element.id() == kFakeCloudThemeId) {
|
const auto currentId = Background()->themeObject().cloud.id;
|
||||||
|
const auto documentId = element.theme.documentId;
|
||||||
|
const auto document = documentId
|
||||||
|
? _window->session().data().document(documentId).get()
|
||||||
|
: nullptr;
|
||||||
|
if (element.id() == kFakeCloudThemeId
|
||||||
|
|| ((element.id() == currentId)
|
||||||
|
&& (!document || !document->isTheme()))) {
|
||||||
element.check->setColors(ColorsFromCurrentTheme());
|
element.check->setColors(ColorsFromCurrentTheme());
|
||||||
} else if (const auto documentId = element.theme.documentId) {
|
} else if (document) {
|
||||||
const auto document = _window->session().data().document(documentId);
|
|
||||||
document->save(Data::FileOrigin(), QString()); // #TODO themes
|
document->save(Data::FileOrigin(), QString()); // #TODO themes
|
||||||
if (document->loaded()) {
|
if (document->loaded()) {
|
||||||
refreshColorsFromDocument(element, document);
|
refreshColorsFromDocument(element, document);
|
||||||
|
@ -598,17 +604,26 @@ bool CloudList::amCreator(const Data::CloudTheme &theme) const {
|
||||||
void CloudList::refreshColorsFromDocument(
|
void CloudList::refreshColorsFromDocument(
|
||||||
Element &element,
|
Element &element,
|
||||||
not_null<DocumentData*> document) {
|
not_null<DocumentData*> document) {
|
||||||
auto colors = ColorsFromTheme(
|
const auto id = element.id();
|
||||||
document->filepath(),
|
const auto path = document->filepath();
|
||||||
document->data());
|
const auto data = document->data();
|
||||||
if (!colors) {
|
crl::async([=, guard = element.generating.make_guard()]() mutable {
|
||||||
|
crl::on_main(std::move(guard), [
|
||||||
|
=,
|
||||||
|
result = ColorsFromTheme(path, data)
|
||||||
|
]() mutable {
|
||||||
|
const auto i = ranges::find(_elements, id, &Element::id);
|
||||||
|
if (i == end(_elements) || !result) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (colors->background.isNull()) {
|
auto &element = *i;
|
||||||
colors->background = ColorsFromCurrentTheme().background;
|
if (result->background.isNull()) {
|
||||||
|
result->background = ColorsFromCurrentTheme().background;
|
||||||
}
|
}
|
||||||
element.check->setColors(*colors);
|
element.check->setColors(*result);
|
||||||
setWaiting(element, false);
|
setWaiting(element, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloudList::subscribeToDownloadFinished() {
|
void CloudList::subscribeToDownloadFinished() {
|
||||||
|
|
|
@ -86,6 +86,7 @@ private:
|
||||||
Data::CloudTheme theme;
|
Data::CloudTheme theme;
|
||||||
not_null<CloudListCheck*> check;
|
not_null<CloudListCheck*> check;
|
||||||
std::unique_ptr<Ui::Radiobutton> button;
|
std::unique_ptr<Ui::Radiobutton> button;
|
||||||
|
base::binary_guard generating;
|
||||||
bool waiting = false;
|
bool waiting = false;
|
||||||
|
|
||||||
uint64 id() const {
|
uint64 id() const {
|
||||||
|
|
Loading…
Add table
Reference in a new issue