mirror of https://github.com/procxx/kepka.git
				
				
				
			Leave only one image source type.
This commit is contained in:
		
							parent
							
								
									6513422e40
								
							
						
					
					
						commit
						d0c78eaddd
					
				| 
						 | 
					@ -117,68 +117,6 @@ constexpr auto kClearSourceTimeout = 10 * crl::time(1000);
 | 
				
			||||||
	return list[index - 1];
 | 
						return list[index - 1];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ImageSource : public Images::Source {
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	explicit ImageSource(
 | 
					 | 
				
			||||||
		EmojiPtr emoji,
 | 
					 | 
				
			||||||
		not_null<crl::object_on_queue<EmojiImageLoader>*> loader);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void load() override;
 | 
					 | 
				
			||||||
	QImage takeLoaded() override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int width() override;
 | 
					 | 
				
			||||||
	int height() override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
	// While HistoryView::Element-s are almost never destroyed
 | 
					 | 
				
			||||||
	// we make loading of the image lazy.
 | 
					 | 
				
			||||||
	not_null<crl::object_on_queue<EmojiImageLoader>*> _loader;
 | 
					 | 
				
			||||||
	EmojiPtr _emoji = nullptr;
 | 
					 | 
				
			||||||
	QImage _data;
 | 
					 | 
				
			||||||
	QSize _size;
 | 
					 | 
				
			||||||
	base::binary_guard _loading;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ImageSource::ImageSource(
 | 
					 | 
				
			||||||
	EmojiPtr emoji,
 | 
					 | 
				
			||||||
	not_null<crl::object_on_queue<EmojiImageLoader>*> loader)
 | 
					 | 
				
			||||||
: _loader(loader)
 | 
					 | 
				
			||||||
, _emoji(emoji)
 | 
					 | 
				
			||||||
, _size(SingleSize()) {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ImageSource::load() {
 | 
					 | 
				
			||||||
	if (!_data.isNull() || _loading) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_loader->with([
 | 
					 | 
				
			||||||
		this,
 | 
					 | 
				
			||||||
		emoji = _emoji,
 | 
					 | 
				
			||||||
		guard = _loading.make_guard()
 | 
					 | 
				
			||||||
	](EmojiImageLoader &loader) mutable {
 | 
					 | 
				
			||||||
		if (!guard) {
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		crl::on_main(std::move(guard), [this, image = loader.prepare(emoji)]{
 | 
					 | 
				
			||||||
			_data = image;
 | 
					 | 
				
			||||||
			Auth().downloaderTaskFinished().notify();
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
QImage ImageSource::takeLoaded() {
 | 
					 | 
				
			||||||
	return _data;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int ImageSource::width() {
 | 
					 | 
				
			||||||
	return _size.width();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int ImageSource::height() {
 | 
					 | 
				
			||||||
	return _size.height();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EmojiImageLoader::EmojiImageLoader(
 | 
					EmojiImageLoader::EmojiImageLoader(
 | 
				
			||||||
| 
						 | 
					@ -264,6 +202,10 @@ std::shared_ptr<UniversalImages> EmojiImageLoader::releaseImages() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace details
 | 
					} // namespace details
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QSize LargeEmojiImage::Size() {
 | 
				
			||||||
 | 
						return details::SingleSize();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EmojiPack::EmojiPack(not_null<Main::Session*> session)
 | 
					EmojiPack::EmojiPack(not_null<Main::Session*> session)
 | 
				
			||||||
: _session(session)
 | 
					: _session(session)
 | 
				
			||||||
, _imageLoader(prepareSourceImages(), session->settings().largeEmoji())
 | 
					, _imageLoader(prepareSourceImages(), session->settings().largeEmoji())
 | 
				
			||||||
| 
						 | 
					@ -347,13 +289,38 @@ auto EmojiPack::stickerForEmoji(const IsolatedEmoji &emoji) -> Sticker {
 | 
				
			||||||
	return Sticker();
 | 
						return Sticker();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::shared_ptr<Image> EmojiPack::image(EmojiPtr emoji) {
 | 
					std::shared_ptr<LargeEmojiImage> EmojiPack::image(EmojiPtr emoji) {
 | 
				
			||||||
	const auto i = _images.emplace(emoji, std::weak_ptr<Image>()).first;
 | 
						const auto i = _images.emplace(
 | 
				
			||||||
 | 
							emoji,
 | 
				
			||||||
 | 
							std::weak_ptr<LargeEmojiImage>()).first;
 | 
				
			||||||
	if (const auto result = i->second.lock()) {
 | 
						if (const auto result = i->second.lock()) {
 | 
				
			||||||
		return result;
 | 
							return result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto result = std::make_shared<Image>(
 | 
						auto result = std::make_shared<LargeEmojiImage>();
 | 
				
			||||||
		std::make_unique<details::ImageSource>(emoji, &_imageLoader));
 | 
						const auto raw = result.get();
 | 
				
			||||||
 | 
						const auto weak = base::make_weak(_session.get());
 | 
				
			||||||
 | 
						raw->load = [=] {
 | 
				
			||||||
 | 
							_imageLoader.with([=](details::EmojiImageLoader &loader) mutable {
 | 
				
			||||||
 | 
								crl::on_main(weak, [
 | 
				
			||||||
 | 
									=,
 | 
				
			||||||
 | 
									image = loader.prepare(emoji)
 | 
				
			||||||
 | 
								]() mutable {
 | 
				
			||||||
 | 
									const auto i = _images.find(emoji);
 | 
				
			||||||
 | 
									if (i != end(_images)) {
 | 
				
			||||||
 | 
										if (const auto strong = i->second.lock()) {
 | 
				
			||||||
 | 
											if (!strong->image) {
 | 
				
			||||||
 | 
												strong->load = nullptr;
 | 
				
			||||||
 | 
												strong->image.emplace(
 | 
				
			||||||
 | 
													std::make_unique<Images::ImageSource>(
 | 
				
			||||||
 | 
														std::move(image)));
 | 
				
			||||||
 | 
												_session->downloaderTaskFinished().notify();
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							raw->load = nullptr;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
	i->second = result;
 | 
						i->second = result;
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,11 +8,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "ui/text/text_isolated_emoji.h"
 | 
					#include "ui/text/text_isolated_emoji.h"
 | 
				
			||||||
 | 
					#include "ui/image/image.h"
 | 
				
			||||||
#include "base/timer.h"
 | 
					#include "base/timer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <crl/crl_object_on_queue.h>
 | 
					#include <crl/crl_object_on_queue.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Image;
 | 
					 | 
				
			||||||
class HistoryItem;
 | 
					class HistoryItem;
 | 
				
			||||||
class DocumentData;
 | 
					class DocumentData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,6 +40,13 @@ class EmojiImageLoader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using IsolatedEmoji = Ui::Text::IsolatedEmoji;
 | 
					using IsolatedEmoji = Ui::Text::IsolatedEmoji;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct LargeEmojiImage {
 | 
				
			||||||
 | 
						std::optional<Image> image;
 | 
				
			||||||
 | 
						FnMut<void()> load;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] static QSize Size();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EmojiPack final {
 | 
					class EmojiPack final {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	struct Sticker {
 | 
						struct Sticker {
 | 
				
			||||||
| 
						 | 
					@ -61,7 +68,7 @@ public:
 | 
				
			||||||
	void remove(not_null<const HistoryItem*> item);
 | 
						void remove(not_null<const HistoryItem*> item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] Sticker stickerForEmoji(const IsolatedEmoji &emoji);
 | 
						[[nodiscard]] Sticker stickerForEmoji(const IsolatedEmoji &emoji);
 | 
				
			||||||
	[[nodiscard]] std::shared_ptr<Image> image(EmojiPtr emoji);
 | 
						[[nodiscard]] std::shared_ptr<LargeEmojiImage> image(EmojiPtr emoji);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	class ImageLoader;
 | 
						class ImageLoader;
 | 
				
			||||||
| 
						 | 
					@ -85,7 +92,7 @@ private:
 | 
				
			||||||
	base::flat_map<
 | 
						base::flat_map<
 | 
				
			||||||
		IsolatedEmoji,
 | 
							IsolatedEmoji,
 | 
				
			||||||
		base::flat_set<not_null<HistoryItem*>>> _items;
 | 
							base::flat_set<not_null<HistoryItem*>>> _items;
 | 
				
			||||||
	base::flat_map<EmojiPtr, std::weak_ptr<Image>> _images;
 | 
						base::flat_map<EmojiPtr, std::weak_ptr<LargeEmojiImage>> _images;
 | 
				
			||||||
	mtpRequestId _requestId = 0;
 | 
						mtpRequestId _requestId = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	crl::object_on_queue<details::EmojiImageLoader> _imageLoader;
 | 
						crl::object_on_queue<details::EmojiImageLoader> _imageLoader;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,10 +20,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
namespace HistoryView {
 | 
					namespace HistoryView {
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using EmojiImage = Stickers::LargeEmojiImage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
auto ResolveImages(
 | 
					auto ResolveImages(
 | 
				
			||||||
	not_null<Main::Session*> session,
 | 
						not_null<Main::Session*> session,
 | 
				
			||||||
	const Ui::Text::IsolatedEmoji &emoji)
 | 
						const Ui::Text::IsolatedEmoji &emoji)
 | 
				
			||||||
-> std::array<std::shared_ptr<Image>, Ui::Text::kIsolatedEmojiLimit> {
 | 
					-> std::array<std::shared_ptr<EmojiImage>, Ui::Text::kIsolatedEmojiLimit> {
 | 
				
			||||||
	const auto single = [&](EmojiPtr emoji) {
 | 
						const auto single = [&](EmojiPtr emoji) {
 | 
				
			||||||
		return emoji ? session->emojiStickersPack().image(emoji) : nullptr;
 | 
							return emoji ? session->emojiStickersPack().image(emoji) : nullptr;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
| 
						 | 
					@ -33,7 +35,7 @@ auto ResolveImages(
 | 
				
			||||||
		single(emoji.items[2]) } };
 | 
							single(emoji.items[2]) } };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
auto NonEmpty(const std::array<std::shared_ptr<Image>, Ui::Text::kIsolatedEmojiLimit> &images) {
 | 
					auto NonEmpty(const std::array<std::shared_ptr<EmojiImage>, Ui::Text::kIsolatedEmojiLimit> &images) {
 | 
				
			||||||
	using namespace rpl::mappers;
 | 
						using namespace rpl::mappers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return images | ranges::view::filter(_1 != nullptr);
 | 
						return images | ranges::view::filter(_1 != nullptr);
 | 
				
			||||||
| 
						 | 
					@ -54,7 +56,7 @@ QSize LargeEmoji::size() {
 | 
				
			||||||
	const auto count = ranges::distance(NonEmpty(_images));
 | 
						const auto count = ranges::distance(NonEmpty(_images));
 | 
				
			||||||
	Assert(count > 0);
 | 
						Assert(count > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const auto single = _images[0]->size() / cIntRetinaFactor();
 | 
						const auto single = EmojiImage::Size() / cIntRetinaFactor();
 | 
				
			||||||
	const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline;
 | 
						const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline;
 | 
				
			||||||
	const auto inner = count * single.width() + (count - 1) * skip;
 | 
						const auto inner = count * single.width() + (count - 1) * skip;
 | 
				
			||||||
	const auto &padding = st::largeEmojiPadding;
 | 
						const auto &padding = st::largeEmojiPadding;
 | 
				
			||||||
| 
						 | 
					@ -71,16 +73,18 @@ void LargeEmoji::draw(Painter &p, const QRect &r, bool selected) {
 | 
				
			||||||
	const auto y = r.y() + (r.height() - _size.height()) / 2 + padding.top();
 | 
						const auto y = r.y() + (r.height() - _size.height()) / 2 + padding.top();
 | 
				
			||||||
	const auto o = Data::FileOrigin();
 | 
						const auto o = Data::FileOrigin();
 | 
				
			||||||
	const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline;
 | 
						const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline;
 | 
				
			||||||
 | 
						const auto size = EmojiImage::Size() / cIntRetinaFactor();
 | 
				
			||||||
	for (const auto &image : images) {
 | 
						for (const auto &image : images) {
 | 
				
			||||||
		image->load();
 | 
							const auto w = size.width();
 | 
				
			||||||
		const auto w = image->width() / cIntRetinaFactor();
 | 
							if (const auto &prepared = image->image) {
 | 
				
			||||||
		if (image->loaded()) {
 | 
								const auto h = size.height();
 | 
				
			||||||
			const auto h = image->height() / cIntRetinaFactor();
 | 
					 | 
				
			||||||
			const auto &c = st::msgStickerOverlay;
 | 
								const auto &c = st::msgStickerOverlay;
 | 
				
			||||||
			const auto pixmap = selected
 | 
								const auto pixmap = selected
 | 
				
			||||||
				? image->pixColored(o, c, w, h)
 | 
									? prepared->pixColored(o, c, w, h)
 | 
				
			||||||
				: image->pix(o, w, h);
 | 
									: prepared->pix(o, w, h);
 | 
				
			||||||
			p.drawPixmap(x, y, pixmap);
 | 
								p.drawPixmap(x, y, pixmap);
 | 
				
			||||||
 | 
							} else if (image->load) {
 | 
				
			||||||
 | 
								image->load();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		x += w + skip;
 | 
							x += w + skip;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,15 +10,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "history/view/media/history_view_media_unwrapped.h"
 | 
					#include "history/view/media/history_view_media_unwrapped.h"
 | 
				
			||||||
#include "ui/text/text_isolated_emoji.h"
 | 
					#include "ui/text/text_isolated_emoji.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Image;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Data {
 | 
					namespace Data {
 | 
				
			||||||
struct FileOrigin;
 | 
					struct FileOrigin;
 | 
				
			||||||
} // namespace Data
 | 
					} // namespace Data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Lottie {
 | 
					namespace Stickers {
 | 
				
			||||||
class SinglePlayer;
 | 
					struct LargeEmojiImage;
 | 
				
			||||||
} // namespace Lottie
 | 
					} // namespace Stickers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace HistoryView {
 | 
					namespace HistoryView {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +36,7 @@ public:
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	const not_null<Element*> _parent;
 | 
						const not_null<Element*> _parent;
 | 
				
			||||||
	const std::array<
 | 
						const std::array<
 | 
				
			||||||
		std::shared_ptr<Image>,
 | 
							std::shared_ptr<Stickers::LargeEmojiImage>,
 | 
				
			||||||
		Ui::Text::kIsolatedEmojiLimit> _images;
 | 
							Ui::Text::kIsolatedEmojiLimit> _images;
 | 
				
			||||||
	QSize _size;
 | 
						QSize _size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue