diff --git a/Telegram/SourceFiles/data/data_cloud_themes.cpp b/Telegram/SourceFiles/data/data_cloud_themes.cpp
index 335a2c7b4..79cf7136a 100644
--- a/Telegram/SourceFiles/data/data_cloud_themes.cpp
+++ b/Telegram/SourceFiles/data/data_cloud_themes.cpp
@@ -272,6 +272,18 @@ void CloudThemes::parseThemes(const QVector<MTPTheme> &list) {
 			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 {
diff --git a/Telegram/SourceFiles/data/data_cloud_themes.h b/Telegram/SourceFiles/data/data_cloud_themes.h
index ea1a87f2c..fcaa036ab 100644
--- a/Telegram/SourceFiles/data/data_cloud_themes.h
+++ b/Telegram/SourceFiles/data/data_cloud_themes.h
@@ -56,6 +56,7 @@ private:
 	};
 
 	void parseThemes(const QVector<MTPTheme> &list);
+	void checkCurrentTheme();
 
 	void install();
 	void setupReload();
diff --git a/Telegram/SourceFiles/window/themes/window_theme.cpp b/Telegram/SourceFiles/window/themes/window_theme.cpp
index 703db24c3..1f159783a 100644
--- a/Telegram/SourceFiles/window/themes/window_theme.cpp
+++ b/Telegram/SourceFiles/window/themes/window_theme.cpp
@@ -259,13 +259,20 @@ bool loadBackground(zlib::FileToRead &file, QByteArray *outBackground, bool *out
 	return true;
 }
 
-bool loadTheme(
+bool LoadTheme(
 		const QByteArray &content,
-		const std::optional<QByteArray> &editedPalette,
-		Cached &cache,
 		const Colorizer &colorizer,
+		const std::optional<QByteArray> &editedPalette,
+		Cached *cache = 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);
 
 	const auto emptyColorizer = Colorizer();
@@ -289,7 +296,9 @@ bool loadTheme(
 		if (!loadColorScheme(schemeContent, paletteColorizer, out)) {
 			return false;
 		}
-		Background()->saveAdjustableColors();
+		if (!out) {
+			Background()->saveAdjustableColors();
+		}
 
 		auto backgroundTiled = false;
 		auto backgroundContent = QByteArray();
@@ -314,30 +323,37 @@ bool loadTheme(
 			if (colorizer) {
 				Colorize(background, colorizer);
 			}
-			auto buffer = QBuffer(&cache.background);
-			if (!background.save(&buffer, "BMP")) {
-				LOG(("Theme Error: could not write background image as a BMP to cache."));
-				return false;
+			if (cache) {
+				auto buffer = QBuffer(&cache->background);
+				if (!background.save(&buffer, "BMP")) {
+					LOG(("Theme Error: could not write background image as a BMP to cache."));
+					return false;
+				}
+				cache->tiled = backgroundTiled;
 			}
-			cache.tiled = backgroundTiled;
-
-			applyBackground(std::move(background), cache.tiled, out);
+			applyBackground(std::move(background), backgroundTiled, out);
 		}
 	} else {
 		// Looks like it is not a .zip theme.
 		if (!loadColorScheme(editedPalette.value_or(content), paletteColorizer, out)) {
 			return false;
 		}
-		Background()->saveAdjustableColors();
+		if (!out) {
+			Background()->saveAdjustableColors();
+		}
 	}
 	if (out) {
-		cache.colors = out->palette.save();
-	} else {
-		cache.colors = style::main_palette::save();
+		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());
 	}
-	cache.paletteChecksum = style::palette::Checksum();
-	cache.contentChecksum = hashCrc32(content.constData(), content.size());
-
 	return true;
 }
 
@@ -396,7 +412,7 @@ bool InitializeFromSaved(Saved &&saved) {
 	}
 
 	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;
 	}
 	if (editing) {
@@ -1046,11 +1062,11 @@ void ChatBackground::reapplyWithNightMode(
 		auto preview = std::make_unique<Preview>();
 		preview->object = std::move(read.object);
 		preview->instance.cached = std::move(read.cache);
-		const auto loaded = loadTheme(
+		const auto loaded = LoadTheme(
 			preview->object.content,
-			std::nullopt,
-			preview->instance.cached,
 			ColorizerForTheme(path),
+			std::nullopt,
+			&preview->instance.cached,
 			&preview->instance);
 		if (!loaded) {
 			return false;
@@ -1252,28 +1268,21 @@ void ResetToSomeDefault() {
 		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(
 		const QString &path,
 		not_null<Instance*> out,
+		Cached *outCache,
 		not_null<QByteArray*> outContent) {
 	*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) {
-	return LoadFromContent(content, out, {});
+bool LoadFromContent(
+		const QByteArray &content,
+		not_null<Instance*> out,
+		Cached *outCache) {
+	return LoadTheme(content, Colorizer(), std::nullopt, outCache, out);
 }
 
 QString EditingPalettePath() {
diff --git a/Telegram/SourceFiles/window/themes/window_theme.h b/Telegram/SourceFiles/window/themes/window_theme.h
index e42f577b2..fc08add93 100644
--- a/Telegram/SourceFiles/window/themes/window_theme.h
+++ b/Telegram/SourceFiles/window/themes/window_theme.h
@@ -84,8 +84,12 @@ void Revert();
 bool LoadFromFile(
 	const QString &file,
 	not_null<Instance*> out,
+	Cached *outCache,
 	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 AdjustedColor(QColor original, QColor background);
 QImage ProcessBackgroundImage(QImage image);
diff --git a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp
index 8284e3e76..56eb4979d 100644
--- a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp
+++ b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp
@@ -925,13 +925,15 @@ std::unique_ptr<Preview> PreviewFromFile(
 	object.pathRelative = filepath.isEmpty()
 		? object.pathAbsolute
 		: QDir().relativeFilePath(filepath);
+	const auto instance = &result->instance;
+	const auto cache = &result->instance.cached;
 	if (bytes.isEmpty()) {
-		if (!LoadFromFile(filepath, &result->instance, &object.content)) {
+		if (!LoadFromFile(filepath, instance, cache, &object.content)) {
 			return nullptr;
 		}
 	} else {
 		object.content = bytes;
-		if (!LoadFromContent(bytes, &result->instance)) {
+		if (!LoadFromContent(bytes, instance, cache)) {
 			return nullptr;
 		}
 	}
diff --git a/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp b/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp
index 684460e38..7a2103084 100644
--- a/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp
+++ b/Telegram/SourceFiles/window/themes/window_themes_cloud_list.cpp
@@ -91,7 +91,7 @@ constexpr auto kShowPerRow = 4;
 		return std::nullopt;
 	}
 	auto instance = Instance();
-	if (!LoadFromContent(content, &instance)) {
+	if (!LoadFromContent(content, &instance, nullptr)) {
 		return std::nullopt;
 	}
 	auto result = CloudListColors();
@@ -519,10 +519,16 @@ void CloudList::refreshElementUsing(
 }
 
 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());
-	} else if (const auto documentId = element.theme.documentId) {
-		const auto document = _window->session().data().document(documentId);
+	} else if (document) {
 		document->save(Data::FileOrigin(), QString()); // #TODO themes
 		if (document->loaded()) {
 			refreshColorsFromDocument(element, document);
@@ -598,17 +604,26 @@ bool CloudList::amCreator(const Data::CloudTheme &theme) const {
 void CloudList::refreshColorsFromDocument(
 		Element &element,
 		not_null<DocumentData*> document) {
-	auto colors = ColorsFromTheme(
-		document->filepath(),
-		document->data());
-	if (!colors) {
-		return;
-	}
-	if (colors->background.isNull()) {
-		colors->background = ColorsFromCurrentTheme().background;
-	}
-	element.check->setColors(*colors);
-	setWaiting(element, false);
+	const auto id = element.id();
+	const auto path = document->filepath();
+	const auto data = document->data();
+	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;
+			}
+			auto &element = *i;
+			if (result->background.isNull()) {
+				result->background = ColorsFromCurrentTheme().background;
+			}
+			element.check->setColors(*result);
+			setWaiting(element, false);
+		});
+	});
 }
 
 void CloudList::subscribeToDownloadFinished() {
diff --git a/Telegram/SourceFiles/window/themes/window_themes_cloud_list.h b/Telegram/SourceFiles/window/themes/window_themes_cloud_list.h
index ff58eea87..83159914f 100644
--- a/Telegram/SourceFiles/window/themes/window_themes_cloud_list.h
+++ b/Telegram/SourceFiles/window/themes/window_themes_cloud_list.h
@@ -86,6 +86,7 @@ private:
 		Data::CloudTheme theme;
 		not_null<CloudListCheck*> check;
 		std::unique_ptr<Ui::Radiobutton> button;
+		base::binary_guard generating;
 		bool waiting = false;
 
 		uint64 id() const {