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];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
EmojiImageLoader::EmojiImageLoader(
 | 
			
		||||
| 
						 | 
				
			
			@ -264,6 +202,10 @@ std::shared_ptr<UniversalImages> EmojiImageLoader::releaseImages() {
 | 
			
		|||
 | 
			
		||||
} // namespace details
 | 
			
		||||
 | 
			
		||||
QSize LargeEmojiImage::Size() {
 | 
			
		||||
	return details::SingleSize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EmojiPack::EmojiPack(not_null<Main::Session*> session)
 | 
			
		||||
: _session(session)
 | 
			
		||||
, _imageLoader(prepareSourceImages(), session->settings().largeEmoji())
 | 
			
		||||
| 
						 | 
				
			
			@ -347,13 +289,38 @@ auto EmojiPack::stickerForEmoji(const IsolatedEmoji &emoji) -> Sticker {
 | 
			
		|||
	return Sticker();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Image> EmojiPack::image(EmojiPtr emoji) {
 | 
			
		||||
	const auto i = _images.emplace(emoji, std::weak_ptr<Image>()).first;
 | 
			
		||||
std::shared_ptr<LargeEmojiImage> EmojiPack::image(EmojiPtr emoji) {
 | 
			
		||||
	const auto i = _images.emplace(
 | 
			
		||||
		emoji,
 | 
			
		||||
		std::weak_ptr<LargeEmojiImage>()).first;
 | 
			
		||||
	if (const auto result = i->second.lock()) {
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	auto result = std::make_shared<Image>(
 | 
			
		||||
		std::make_unique<details::ImageSource>(emoji, &_imageLoader));
 | 
			
		||||
	auto result = std::make_shared<LargeEmojiImage>();
 | 
			
		||||
	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;
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,11 +8,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "ui/text/text_isolated_emoji.h"
 | 
			
		||||
#include "ui/image/image.h"
 | 
			
		||||
#include "base/timer.h"
 | 
			
		||||
 | 
			
		||||
#include <crl/crl_object_on_queue.h>
 | 
			
		||||
 | 
			
		||||
class Image;
 | 
			
		||||
class HistoryItem;
 | 
			
		||||
class DocumentData;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +40,13 @@ class EmojiImageLoader;
 | 
			
		|||
 | 
			
		||||
using IsolatedEmoji = Ui::Text::IsolatedEmoji;
 | 
			
		||||
 | 
			
		||||
struct LargeEmojiImage {
 | 
			
		||||
	std::optional<Image> image;
 | 
			
		||||
	FnMut<void()> load;
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] static QSize Size();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class EmojiPack final {
 | 
			
		||||
public:
 | 
			
		||||
	struct Sticker {
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +68,7 @@ public:
 | 
			
		|||
	void remove(not_null<const HistoryItem*> item);
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] Sticker stickerForEmoji(const IsolatedEmoji &emoji);
 | 
			
		||||
	[[nodiscard]] std::shared_ptr<Image> image(EmojiPtr emoji);
 | 
			
		||||
	[[nodiscard]] std::shared_ptr<LargeEmojiImage> image(EmojiPtr emoji);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	class ImageLoader;
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +92,7 @@ private:
 | 
			
		|||
	base::flat_map<
 | 
			
		||||
		IsolatedEmoji,
 | 
			
		||||
		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;
 | 
			
		||||
 | 
			
		||||
	crl::object_on_queue<details::EmojiImageLoader> _imageLoader;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,10 +20,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
namespace HistoryView {
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
using EmojiImage = Stickers::LargeEmojiImage;
 | 
			
		||||
 | 
			
		||||
auto ResolveImages(
 | 
			
		||||
	not_null<Main::Session*> session,
 | 
			
		||||
	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) {
 | 
			
		||||
		return emoji ? session->emojiStickersPack().image(emoji) : nullptr;
 | 
			
		||||
	};
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +35,7 @@ auto ResolveImages(
 | 
			
		|||
		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;
 | 
			
		||||
 | 
			
		||||
	return images | ranges::view::filter(_1 != nullptr);
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +56,7 @@ QSize LargeEmoji::size() {
 | 
			
		|||
	const auto count = ranges::distance(NonEmpty(_images));
 | 
			
		||||
	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 inner = count * single.width() + (count - 1) * skip;
 | 
			
		||||
	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 o = Data::FileOrigin();
 | 
			
		||||
	const auto skip = st::largeEmojiSkip - 2 * st::largeEmojiOutline;
 | 
			
		||||
	const auto size = EmojiImage::Size() / cIntRetinaFactor();
 | 
			
		||||
	for (const auto &image : images) {
 | 
			
		||||
		image->load();
 | 
			
		||||
		const auto w = image->width() / cIntRetinaFactor();
 | 
			
		||||
		if (image->loaded()) {
 | 
			
		||||
			const auto h = image->height() / cIntRetinaFactor();
 | 
			
		||||
		const auto w = size.width();
 | 
			
		||||
		if (const auto &prepared = image->image) {
 | 
			
		||||
			const auto h = size.height();
 | 
			
		||||
			const auto &c = st::msgStickerOverlay;
 | 
			
		||||
			const auto pixmap = selected
 | 
			
		||||
				? image->pixColored(o, c, w, h)
 | 
			
		||||
				: image->pix(o, w, h);
 | 
			
		||||
				? prepared->pixColored(o, c, w, h)
 | 
			
		||||
				: prepared->pix(o, w, h);
 | 
			
		||||
			p.drawPixmap(x, y, pixmap);
 | 
			
		||||
		} else if (image->load) {
 | 
			
		||||
			image->load();
 | 
			
		||||
		}
 | 
			
		||||
		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 "ui/text/text_isolated_emoji.h"
 | 
			
		||||
 | 
			
		||||
class Image;
 | 
			
		||||
 | 
			
		||||
namespace Data {
 | 
			
		||||
struct FileOrigin;
 | 
			
		||||
} // namespace Data
 | 
			
		||||
 | 
			
		||||
namespace Lottie {
 | 
			
		||||
class SinglePlayer;
 | 
			
		||||
} // namespace Lottie
 | 
			
		||||
namespace Stickers {
 | 
			
		||||
struct LargeEmojiImage;
 | 
			
		||||
} // namespace Stickers
 | 
			
		||||
 | 
			
		||||
namespace HistoryView {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +36,7 @@ public:
 | 
			
		|||
private:
 | 
			
		||||
	const not_null<Element*> _parent;
 | 
			
		||||
	const std::array<
 | 
			
		||||
		std::shared_ptr<Image>,
 | 
			
		||||
		std::shared_ptr<Stickers::LargeEmojiImage>,
 | 
			
		||||
		Ui::Text::kIsolatedEmojiLimit> _images;
 | 
			
		||||
	QSize _size;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue