mirror of https://github.com/procxx/kepka.git
				
				
				
			Implement dice media display.
This commit is contained in:
		
							parent
							
								
									d4b9b65724
								
							
						
					
					
						commit
						c83e297554
					
				| 
						 | 
					@ -270,6 +270,8 @@ PRIVATE
 | 
				
			||||||
    chat_helpers/stickers.h
 | 
					    chat_helpers/stickers.h
 | 
				
			||||||
    chat_helpers/stickers_emoji_pack.cpp
 | 
					    chat_helpers/stickers_emoji_pack.cpp
 | 
				
			||||||
    chat_helpers/stickers_emoji_pack.h
 | 
					    chat_helpers/stickers_emoji_pack.h
 | 
				
			||||||
 | 
					    chat_helpers/stickers_dice_pack.cpp
 | 
				
			||||||
 | 
					    chat_helpers/stickers_dice_pack.h
 | 
				
			||||||
    chat_helpers/stickers_list_widget.cpp
 | 
					    chat_helpers/stickers_list_widget.cpp
 | 
				
			||||||
    chat_helpers/stickers_list_widget.h
 | 
					    chat_helpers/stickers_list_widget.h
 | 
				
			||||||
    chat_helpers/tabbed_panel.cpp
 | 
					    chat_helpers/tabbed_panel.cpp
 | 
				
			||||||
| 
						 | 
					@ -436,6 +438,8 @@ PRIVATE
 | 
				
			||||||
    history/view/media/history_view_call.cpp
 | 
					    history/view/media/history_view_call.cpp
 | 
				
			||||||
    history/view/media/history_view_contact.h
 | 
					    history/view/media/history_view_contact.h
 | 
				
			||||||
    history/view/media/history_view_contact.cpp
 | 
					    history/view/media/history_view_contact.cpp
 | 
				
			||||||
 | 
					    history/view/media/history_view_dice.h
 | 
				
			||||||
 | 
					    history/view/media/history_view_dice.cpp
 | 
				
			||||||
    history/view/media/history_view_document.h
 | 
					    history/view/media/history_view_document.h
 | 
				
			||||||
    history/view/media/history_view_document.cpp
 | 
					    history/view/media/history_view_document.cpp
 | 
				
			||||||
    history/view/media/history_view_file.h
 | 
					    history/view/media/history_view_file.h
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -47,6 +47,7 @@
 | 
				
			||||||
    <file alias="art/logo_256.png">../../art/logo_256.png</file>
 | 
					    <file alias="art/logo_256.png">../../art/logo_256.png</file>
 | 
				
			||||||
    <file alias="art/logo_256_no_margin.png">../../art/logo_256_no_margin.png</file>
 | 
					    <file alias="art/logo_256_no_margin.png">../../art/logo_256_no_margin.png</file>
 | 
				
			||||||
    <file alias="art/sunrise.jpg">../../art/sunrise.jpg</file>
 | 
					    <file alias="art/sunrise.jpg">../../art/sunrise.jpg</file>
 | 
				
			||||||
 | 
					    <file alias="art/dice_idle.tgs">../../art/dice_idle.tgs</file>
 | 
				
			||||||
    <file alias="day-blue.tdesktop-theme">../../day-blue.tdesktop-theme</file>
 | 
					    <file alias="day-blue.tdesktop-theme">../../day-blue.tdesktop-theme</file>
 | 
				
			||||||
    <file alias="night.tdesktop-theme">../../night.tdesktop-theme</file>
 | 
					    <file alias="night.tdesktop-theme">../../night.tdesktop-theme</file>
 | 
				
			||||||
    <file alias="night-green.tdesktop-theme">../../night-green.tdesktop-theme</file>
 | 
					    <file alias="night-green.tdesktop-theme">../../night-green.tdesktop-theme</file>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,96 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					This file is part of Telegram Desktop,
 | 
				
			||||||
 | 
					the official desktop application for the Telegram messaging service.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For license and copyright information please follow this link:
 | 
				
			||||||
 | 
					https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#include "chat_helpers/stickers_dice_pack.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "main/main_session.h"
 | 
				
			||||||
 | 
					#include "data/data_session.h"
 | 
				
			||||||
 | 
					#include "data/data_document.h"
 | 
				
			||||||
 | 
					#include "storage/localimageloader.h"
 | 
				
			||||||
 | 
					#include "base/unixtime.h"
 | 
				
			||||||
 | 
					#include "apiwrap.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QtCore/QFile>
 | 
				
			||||||
 | 
					#include <QtCore/QFileInfo>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Stickers {
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr auto kZeroDiceDocumentId = 0xa3b83c9f84fa9e83ULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DicePack::DicePack(not_null<Main::Session*> session)
 | 
				
			||||||
 | 
					: _session(session) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DicePack::~DicePack() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DocumentData *DicePack::lookup(int value) {
 | 
				
			||||||
 | 
						if (!_requestId) {
 | 
				
			||||||
 | 
							load();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!value) {
 | 
				
			||||||
 | 
							ensureZeroGenerated();
 | 
				
			||||||
 | 
							return _zero;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						const auto i = _map.find(value);
 | 
				
			||||||
 | 
						return (i != end(_map)) ? i->second.get() : nullptr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DicePack::load() {
 | 
				
			||||||
 | 
						if (_requestId) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_requestId = _session->api().request(MTPmessages_GetStickerSet(
 | 
				
			||||||
 | 
							MTP_inputStickerSetDice()
 | 
				
			||||||
 | 
						)).done([=](const MTPmessages_StickerSet &result) {
 | 
				
			||||||
 | 
							result.match([&](const MTPDmessages_stickerSet &data) {
 | 
				
			||||||
 | 
								applySet(data);
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}).fail([=](const RPCError &error) {
 | 
				
			||||||
 | 
							_requestId = 0;
 | 
				
			||||||
 | 
						}).send();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DicePack::applySet(const MTPDmessages_stickerSet &data) {
 | 
				
			||||||
 | 
						auto index = 0;
 | 
				
			||||||
 | 
						for (const auto &sticker : data.vdocuments().v) {
 | 
				
			||||||
 | 
							const auto document = _session->data().processDocument(
 | 
				
			||||||
 | 
								sticker);
 | 
				
			||||||
 | 
							if (document->sticker()) {
 | 
				
			||||||
 | 
								_map.emplace(++index, document);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DicePack::ensureZeroGenerated() {
 | 
				
			||||||
 | 
						if (_zero) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const auto path = qsl(":/gui/art/dice_idle.tgs");
 | 
				
			||||||
 | 
						auto task = FileLoadTask(
 | 
				
			||||||
 | 
							path,
 | 
				
			||||||
 | 
							QByteArray(),
 | 
				
			||||||
 | 
							nullptr,
 | 
				
			||||||
 | 
							SendMediaType::File,
 | 
				
			||||||
 | 
							FileLoadTo(0, {}, 0),
 | 
				
			||||||
 | 
							{});
 | 
				
			||||||
 | 
						task.process();
 | 
				
			||||||
 | 
						const auto result = task.peekResult();
 | 
				
			||||||
 | 
						Assert(result != nullptr);
 | 
				
			||||||
 | 
						_zero = _session->data().processDocument(
 | 
				
			||||||
 | 
							result->document,
 | 
				
			||||||
 | 
							std::move(result->thumb));
 | 
				
			||||||
 | 
						_zero->setLocation(FileLocation(path));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Ensures(_zero->sticker());
 | 
				
			||||||
 | 
						Ensures(_zero->sticker()->animated);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Stickers
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,37 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					This file is part of Telegram Desktop,
 | 
				
			||||||
 | 
					the official desktop application for the Telegram messaging service.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For license and copyright information please follow this link:
 | 
				
			||||||
 | 
					https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DocumentData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Main {
 | 
				
			||||||
 | 
					class Session;
 | 
				
			||||||
 | 
					} // namespace Main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Stickers {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DicePack final {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						explicit DicePack(not_null<Main::Session*> session);
 | 
				
			||||||
 | 
						~DicePack();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DocumentData *lookup(int value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						void load();
 | 
				
			||||||
 | 
						void applySet(const MTPDmessages_stickerSet &data);
 | 
				
			||||||
 | 
						void ensureZeroGenerated();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						not_null<Main::Session*> _session;
 | 
				
			||||||
 | 
						base::flat_map<int, not_null<DocumentData*>> _map;
 | 
				
			||||||
 | 
						DocumentData *_zero = nullptr;
 | 
				
			||||||
 | 
						mtpRequestId _requestId = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace Stickers
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "history/view/media/history_view_web_page.h"
 | 
					#include "history/view/media/history_view_web_page.h"
 | 
				
			||||||
#include "history/view/media/history_view_poll.h"
 | 
					#include "history/view/media/history_view_poll.h"
 | 
				
			||||||
#include "history/view/media/history_view_theme_document.h"
 | 
					#include "history/view/media/history_view_theme_document.h"
 | 
				
			||||||
 | 
					#include "history/view/media/history_view_dice.h"
 | 
				
			||||||
#include "ui/image/image.h"
 | 
					#include "ui/image/image.h"
 | 
				
			||||||
#include "ui/image/image_source.h"
 | 
					#include "ui/image/image_source.h"
 | 
				
			||||||
#include "ui/text_options.h"
 | 
					#include "ui/text_options.h"
 | 
				
			||||||
| 
						 | 
					@ -1325,4 +1326,49 @@ std::unique_ptr<HistoryView::Media> MediaPoll::createView(
 | 
				
			||||||
	return std::make_unique<HistoryView::Poll>(message, _poll);
 | 
						return std::make_unique<HistoryView::Poll>(message, _poll);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MediaDice::MediaDice(not_null<HistoryItem*> parent, int value)
 | 
				
			||||||
 | 
					: Media(parent)
 | 
				
			||||||
 | 
					, _value(value) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::unique_ptr<Media> MediaDice::clone(not_null<HistoryItem*> parent) {
 | 
				
			||||||
 | 
						return std::make_unique<MediaDice>(parent, _value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int MediaDice::diceValue() const {
 | 
				
			||||||
 | 
						return _value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString MediaDice::notificationText() const {
 | 
				
			||||||
 | 
						return QString::fromUtf8("\xF0\x9F\x8E\xB2");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString MediaDice::pinnedTextSubstring() const {
 | 
				
			||||||
 | 
						return QChar(171) + notificationText() + QChar(187);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TextForMimeData MediaDice::clipboardText() const {
 | 
				
			||||||
 | 
						return { notificationText() };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool MediaDice::updateInlineResultMedia(const MTPMessageMedia &media) {
 | 
				
			||||||
 | 
						return updateSentMedia(media);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool MediaDice::updateSentMedia(const MTPMessageMedia &media) {
 | 
				
			||||||
 | 
						if (media.type() != mtpc_messageMediaDice) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_value = media.c_messageMediaDice().vvalue().v;
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::unique_ptr<HistoryView::Media> MediaDice::createView(
 | 
				
			||||||
 | 
							not_null<HistoryView::Element*> message,
 | 
				
			||||||
 | 
							not_null<HistoryItem*> realParent) {
 | 
				
			||||||
 | 
						return std::make_unique<HistoryView::UnwrappedMedia>(
 | 
				
			||||||
 | 
							message,
 | 
				
			||||||
 | 
							std::make_unique<HistoryView::Dice>(message, _value));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Data
 | 
					} // namespace Data
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,7 +118,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaPhoto : public Media {
 | 
					class MediaPhoto final : public Media {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	MediaPhoto(
 | 
						MediaPhoto(
 | 
				
			||||||
		not_null<HistoryItem*> parent,
 | 
							not_null<HistoryItem*> parent,
 | 
				
			||||||
| 
						 | 
					@ -158,7 +158,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaFile : public Media {
 | 
					class MediaFile final : public Media {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	MediaFile(
 | 
						MediaFile(
 | 
				
			||||||
		not_null<HistoryItem*> parent,
 | 
							not_null<HistoryItem*> parent,
 | 
				
			||||||
| 
						 | 
					@ -195,7 +195,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaContact : public Media {
 | 
					class MediaContact final : public Media {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	MediaContact(
 | 
						MediaContact(
 | 
				
			||||||
		not_null<HistoryItem*> parent,
 | 
							not_null<HistoryItem*> parent,
 | 
				
			||||||
| 
						 | 
					@ -223,7 +223,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaLocation : public Media {
 | 
					class MediaLocation final : public Media {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	MediaLocation(
 | 
						MediaLocation(
 | 
				
			||||||
		not_null<HistoryItem*> parent,
 | 
							not_null<HistoryItem*> parent,
 | 
				
			||||||
| 
						 | 
					@ -255,7 +255,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaCall : public Media {
 | 
					class MediaCall final : public Media {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	MediaCall(
 | 
						MediaCall(
 | 
				
			||||||
		not_null<HistoryItem*> parent,
 | 
							not_null<HistoryItem*> parent,
 | 
				
			||||||
| 
						 | 
					@ -284,7 +284,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaWebPage : public Media {
 | 
					class MediaWebPage final : public Media {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	MediaWebPage(
 | 
						MediaWebPage(
 | 
				
			||||||
		not_null<HistoryItem*> parent,
 | 
							not_null<HistoryItem*> parent,
 | 
				
			||||||
| 
						 | 
					@ -316,7 +316,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaGame : public Media {
 | 
					class MediaGame final : public Media {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	MediaGame(
 | 
						MediaGame(
 | 
				
			||||||
		not_null<HistoryItem*> parent,
 | 
							not_null<HistoryItem*> parent,
 | 
				
			||||||
| 
						 | 
					@ -348,7 +348,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaInvoice : public Media {
 | 
					class MediaInvoice final : public Media {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	MediaInvoice(
 | 
						MediaInvoice(
 | 
				
			||||||
		not_null<HistoryItem*> parent,
 | 
							not_null<HistoryItem*> parent,
 | 
				
			||||||
| 
						 | 
					@ -378,7 +378,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaPoll : public Media {
 | 
					class MediaPoll final : public Media {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	MediaPoll(
 | 
						MediaPoll(
 | 
				
			||||||
		not_null<HistoryItem*> parent,
 | 
							not_null<HistoryItem*> parent,
 | 
				
			||||||
| 
						 | 
					@ -405,6 +405,28 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MediaDice final : public Media {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						MediaDice(not_null<HistoryItem*> parent, int value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int diceValue() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QString notificationText() const override;
 | 
				
			||||||
 | 
						QString pinnedTextSubstring() const override;
 | 
				
			||||||
 | 
						TextForMimeData clipboardText() const override;
 | 
				
			||||||
 | 
						bool updateInlineResultMedia(const MTPMessageMedia &media) override;
 | 
				
			||||||
 | 
						bool updateSentMedia(const MTPMessageMedia &media) override;
 | 
				
			||||||
 | 
						std::unique_ptr<HistoryView::Media> createView(
 | 
				
			||||||
 | 
							not_null<HistoryView::Element*> message,
 | 
				
			||||||
 | 
							not_null<HistoryItem*> realParent) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						int _value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TextForMimeData WithCaptionClipboardText(
 | 
					TextForMimeData WithCaptionClipboardText(
 | 
				
			||||||
	const QString &attachType,
 | 
						const QString &attachType,
 | 
				
			||||||
	TextForMimeData &&caption);
 | 
						TextForMimeData &&caption);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -154,7 +154,7 @@ MediaCheckResult CheckMessageMedia(const MTPMessageMedia &media) {
 | 
				
			||||||
	}, [](const MTPDmessageMediaPoll &) {
 | 
						}, [](const MTPDmessageMediaPoll &) {
 | 
				
			||||||
		return Result::Good;
 | 
							return Result::Good;
 | 
				
			||||||
	}, [](const MTPDmessageMediaDice &) {
 | 
						}, [](const MTPDmessageMediaDice &) {
 | 
				
			||||||
		return Result::Unsupported; // #TODO dice
 | 
							return Result::Good;
 | 
				
			||||||
	}, [](const MTPDmessageMediaUnsupported &) {
 | 
						}, [](const MTPDmessageMediaUnsupported &) {
 | 
				
			||||||
		return Result::Unsupported;
 | 
							return Result::Unsupported;
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1024,8 +1024,8 @@ std::unique_ptr<Data::Media> HistoryMessage::CreateMedia(
 | 
				
			||||||
		return std::make_unique<Data::MediaPoll>(
 | 
							return std::make_unique<Data::MediaPoll>(
 | 
				
			||||||
			item,
 | 
								item,
 | 
				
			||||||
			item->history()->owner().processPoll(media));
 | 
								item->history()->owner().processPoll(media));
 | 
				
			||||||
	}, [](const MTPDmessageMediaDice &media) -> Result {
 | 
						}, [&](const MTPDmessageMediaDice &media) -> Result {
 | 
				
			||||||
		return nullptr; // #TODO dice
 | 
							return std::make_unique<Data::MediaDice>(item, media.vvalue().v);
 | 
				
			||||||
	}, [](const MTPDmessageMediaEmpty &) -> Result {
 | 
						}, [](const MTPDmessageMediaEmpty &) -> Result {
 | 
				
			||||||
		return nullptr;
 | 
							return nullptr;
 | 
				
			||||||
	}, [](const MTPDmessageMediaUnsupported &) -> Result {
 | 
						}, [](const MTPDmessageMediaUnsupported &) -> Result {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,60 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					This file is part of Telegram Desktop,
 | 
				
			||||||
 | 
					the official desktop application for the Telegram messaging service.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For license and copyright information please follow this link:
 | 
				
			||||||
 | 
					https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#include "history/view/media/history_view_dice.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "data/data_session.h"
 | 
				
			||||||
 | 
					#include "chat_helpers/stickers_dice_pack.h"
 | 
				
			||||||
 | 
					#include "history/history.h"
 | 
				
			||||||
 | 
					#include "history/history_item.h"
 | 
				
			||||||
 | 
					#include "history/view/history_view_element.h"
 | 
				
			||||||
 | 
					#include "main/main_session.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace HistoryView {
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DocumentData *Lookup(not_null<Element*> view, int value) {
 | 
				
			||||||
 | 
						const auto &session = view->data()->history()->session();
 | 
				
			||||||
 | 
						return session.diceStickersPack().lookup(value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Dice::Dice(not_null<Element*> parent, int value)
 | 
				
			||||||
 | 
					: _parent(parent)
 | 
				
			||||||
 | 
					, _start(parent, Lookup(parent, 0))
 | 
				
			||||||
 | 
					, _value(value) {
 | 
				
			||||||
 | 
						_start.setDiceIndex(0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Dice::~Dice() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QSize Dice::size() {
 | 
				
			||||||
 | 
						return _start.size();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Dice::draw(Painter &p, const QRect &r, bool selected) {
 | 
				
			||||||
 | 
						Expects(_end.has_value() || !_drawingEnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (_drawingEnd) {
 | 
				
			||||||
 | 
							_end->draw(p, r, selected);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							_start.draw(p, r, selected);
 | 
				
			||||||
 | 
							if (!_end && _value) {
 | 
				
			||||||
 | 
								if (const auto document = Lookup(_parent, _value)) {
 | 
				
			||||||
 | 
									_end.emplace(_parent, document);
 | 
				
			||||||
 | 
									_end->setDiceIndex(_value);
 | 
				
			||||||
 | 
									_end->initSize();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (_end && _end->readyToDrawLottie() && _start.atTheEnd()) {
 | 
				
			||||||
 | 
								_drawingEnd = true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace HistoryView
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,43 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					This file is part of Telegram Desktop,
 | 
				
			||||||
 | 
					the official desktop application for the Telegram messaging service.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For license and copyright information please follow this link:
 | 
				
			||||||
 | 
					https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "history/view/media/history_view_media_unwrapped.h"
 | 
				
			||||||
 | 
					#include "history/view/media/history_view_sticker.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace HistoryView {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Dice final : public UnwrappedMedia::Content {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						Dice(not_null<Element*> parent, int value);
 | 
				
			||||||
 | 
						~Dice();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QSize size() override;
 | 
				
			||||||
 | 
						void draw(Painter &p, const QRect &r, bool selected) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void clearStickerLoopPlayed() override {
 | 
				
			||||||
 | 
							_lottieOncePlayed = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						void unloadHeavyPart() override {
 | 
				
			||||||
 | 
							_start.unloadHeavyPart();
 | 
				
			||||||
 | 
							if (_end) {
 | 
				
			||||||
 | 
								_end->unloadHeavyPart();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						const not_null<Element*> _parent;
 | 
				
			||||||
 | 
						std::optional<Sticker> _end;
 | 
				
			||||||
 | 
						Sticker _start;
 | 
				
			||||||
 | 
						int _value = 0;
 | 
				
			||||||
 | 
						mutable bool _lottieOncePlayed = false;
 | 
				
			||||||
 | 
						mutable bool _drawingEnd = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace HistoryView
 | 
				
			||||||
| 
						 | 
					@ -57,7 +57,7 @@ bool Sticker::isEmojiSticker() const {
 | 
				
			||||||
	return (_parent->data()->media() == nullptr);
 | 
						return (_parent->data()->media() == nullptr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QSize Sticker::size() {
 | 
					void Sticker::initSize() {
 | 
				
			||||||
	_size = _document->dimensions;
 | 
						_size = _document->dimensions;
 | 
				
			||||||
	if (isEmojiSticker()) {
 | 
						if (isEmojiSticker()) {
 | 
				
			||||||
		constexpr auto kIdealStickerSize = 512;
 | 
							constexpr auto kIdealStickerSize = 512;
 | 
				
			||||||
| 
						 | 
					@ -70,14 +70,22 @@ QSize Sticker::size() {
 | 
				
			||||||
		_size = DownscaledSize(
 | 
							_size = DownscaledSize(
 | 
				
			||||||
			_size,
 | 
								_size,
 | 
				
			||||||
			{ st::maxStickerSize, st::maxStickerSize });
 | 
								{ st::maxStickerSize, st::maxStickerSize });
 | 
				
			||||||
 | 
							[[maybe_unused]] bool result = readyToDrawLottie();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QSize Sticker::size() {
 | 
				
			||||||
 | 
						initSize();
 | 
				
			||||||
	return _size;
 | 
						return _size;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Sticker::draw(Painter &p, const QRect &r, bool selected) {
 | 
					bool Sticker::readyToDrawLottie() {
 | 
				
			||||||
 | 
						if (!_lastDiceFrame.isNull()) {
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	const auto sticker = _document->sticker();
 | 
						const auto sticker = _document->sticker();
 | 
				
			||||||
	if (!sticker) {
 | 
						if (!sticker) {
 | 
				
			||||||
		return;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_document->checkStickerLarge();
 | 
						_document->checkStickerLarge();
 | 
				
			||||||
| 
						 | 
					@ -85,10 +93,14 @@ void Sticker::draw(Painter &p, const QRect &r, bool selected) {
 | 
				
			||||||
	if (sticker->animated && !_lottie && loaded) {
 | 
						if (sticker->animated && !_lottie && loaded) {
 | 
				
			||||||
		setupLottie();
 | 
							setupLottie();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return (_lottie && _lottie->ready());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (_lottie && _lottie->ready()) {
 | 
					void Sticker::draw(Painter &p, const QRect &r, bool selected) {
 | 
				
			||||||
 | 
						if (readyToDrawLottie()) {
 | 
				
			||||||
		paintLottie(p, r, selected);
 | 
							paintLottie(p, r, selected);
 | 
				
			||||||
	} else if (!sticker->animated || !_replacements) {
 | 
						} else if (_document->sticker()
 | 
				
			||||||
 | 
							&& (!_document->sticker()->animated || !_replacements)) {
 | 
				
			||||||
		paintPixmap(p, r, selected);
 | 
							paintPixmap(p, r, selected);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -96,24 +108,51 @@ void Sticker::draw(Painter &p, const QRect &r, bool selected) {
 | 
				
			||||||
void Sticker::paintLottie(Painter &p, const QRect &r, bool selected) {
 | 
					void Sticker::paintLottie(Painter &p, const QRect &r, bool selected) {
 | 
				
			||||||
	auto request = Lottie::FrameRequest();
 | 
						auto request = Lottie::FrameRequest();
 | 
				
			||||||
	request.box = _size * cIntRetinaFactor();
 | 
						request.box = _size * cIntRetinaFactor();
 | 
				
			||||||
	if (selected) {
 | 
						if (selected && !_nextLastDiceFrame) {
 | 
				
			||||||
		request.colored = st::msgStickerOverlay->c;
 | 
							request.colored = st::msgStickerOverlay->c;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	const auto frame = _lottie->frameInfo(request);
 | 
						const auto frame = _lottie
 | 
				
			||||||
	const auto size = frame.image.size() / cIntRetinaFactor();
 | 
							? _lottie->frameInfo(request)
 | 
				
			||||||
 | 
							: Lottie::Animation::FrameInfo();
 | 
				
			||||||
 | 
						if (_nextLastDiceFrame) {
 | 
				
			||||||
 | 
							_nextLastDiceFrame = false;
 | 
				
			||||||
 | 
							_lastDiceFrame = frame.image;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						const auto &image = _lastDiceFrame.isNull()
 | 
				
			||||||
 | 
							? frame.image
 | 
				
			||||||
 | 
							: _lastDiceFrame;
 | 
				
			||||||
 | 
						const auto prepared = (!_lastDiceFrame.isNull() && selected)
 | 
				
			||||||
 | 
							? Images::prepareColored(st::msgStickerOverlay->c, image)
 | 
				
			||||||
 | 
							: image;
 | 
				
			||||||
 | 
						const auto size = prepared.size() / cIntRetinaFactor();
 | 
				
			||||||
	p.drawImage(
 | 
						p.drawImage(
 | 
				
			||||||
		QRect(
 | 
							QRect(
 | 
				
			||||||
			QPoint(
 | 
								QPoint(
 | 
				
			||||||
				r.x() + (r.width() - size.width()) / 2,
 | 
									r.x() + (r.width() - size.width()) / 2,
 | 
				
			||||||
				r.y() + (r.height() - size.height()) / 2),
 | 
									r.y() + (r.height() - size.height()) / 2),
 | 
				
			||||||
			size),
 | 
								size),
 | 
				
			||||||
		frame.image);
 | 
							prepared);
 | 
				
			||||||
 | 
						if (!_lastDiceFrame.isNull()) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const auto paused = App::wnd()->sessionController()->isGifPausedAtLeastFor(Window::GifPauseReason::Any);
 | 
						const auto paused = App::wnd()->sessionController()->isGifPausedAtLeastFor(Window::GifPauseReason::Any);
 | 
				
			||||||
	const auto playOnce = isEmojiSticker()
 | 
						const auto playOnce = (_diceIndex > 0)
 | 
				
			||||||
		|| !_document->session().settings().loopAnimatedStickers();
 | 
							? true
 | 
				
			||||||
 | 
							: (_diceIndex == 0)
 | 
				
			||||||
 | 
							? false
 | 
				
			||||||
 | 
							: (isEmojiSticker()
 | 
				
			||||||
 | 
								|| !_document->session().settings().loopAnimatedStickers());
 | 
				
			||||||
 | 
						const auto count = _lottie->information().framesCount;
 | 
				
			||||||
 | 
						_atTheEnd = (frame.index + 1 == count);
 | 
				
			||||||
 | 
						_nextLastDiceFrame = !paused
 | 
				
			||||||
 | 
							&& (_diceIndex > 0)
 | 
				
			||||||
 | 
							&& (frame.index + 2 == count);
 | 
				
			||||||
 | 
						const auto lastDiceFrame = (_diceIndex > 0) && _atTheEnd;
 | 
				
			||||||
 | 
						const auto switchToNext = !playOnce
 | 
				
			||||||
 | 
							|| (!lastDiceFrame && (frame.index != 0 || !_lottieOncePlayed));
 | 
				
			||||||
	if (!paused
 | 
						if (!paused
 | 
				
			||||||
		&& (!playOnce || frame.index != 0 || !_lottieOncePlayed)
 | 
							&& switchToNext
 | 
				
			||||||
		&& _lottie->markFrameShown()
 | 
							&& _lottie->markFrameShown()
 | 
				
			||||||
		&& playOnce
 | 
							&& playOnce
 | 
				
			||||||
		&& !_lottieOncePlayed) {
 | 
							&& !_lottieOncePlayed) {
 | 
				
			||||||
| 
						 | 
					@ -188,6 +227,10 @@ void Sticker::refreshLink() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Sticker::setDiceIndex(int index) {
 | 
				
			||||||
 | 
						_diceIndex = index;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Sticker::setupLottie() {
 | 
					void Sticker::setupLottie() {
 | 
				
			||||||
	_lottie = Stickers::LottiePlayerFromDocument(
 | 
						_lottie = Stickers::LottiePlayerFromDocument(
 | 
				
			||||||
		_document,
 | 
							_document,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,7 @@ public:
 | 
				
			||||||
		const Lottie::ColorReplacements *replacements = nullptr);
 | 
							const Lottie::ColorReplacements *replacements = nullptr);
 | 
				
			||||||
	~Sticker();
 | 
						~Sticker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void initSize();
 | 
				
			||||||
	QSize size() override;
 | 
						QSize size() override;
 | 
				
			||||||
	void draw(Painter &p, const QRect &r, bool selected) override;
 | 
						void draw(Painter &p, const QRect &r, bool selected) override;
 | 
				
			||||||
	ClickHandlerPtr link() override {
 | 
						ClickHandlerPtr link() override {
 | 
				
			||||||
| 
						 | 
					@ -48,6 +49,12 @@ public:
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	void refreshLink() override;
 | 
						void refreshLink() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void setDiceIndex(int index);
 | 
				
			||||||
 | 
						[[nodiscard]] bool atTheEnd() const {
 | 
				
			||||||
 | 
							return _atTheEnd;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						[[nodiscard]] bool readyToDrawLottie();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	[[nodiscard]] bool isEmojiSticker() const;
 | 
						[[nodiscard]] bool isEmojiSticker() const;
 | 
				
			||||||
	void paintLottie(Painter &p, const QRect &r, bool selected);
 | 
						void paintLottie(Painter &p, const QRect &r, bool selected);
 | 
				
			||||||
| 
						 | 
					@ -63,7 +70,11 @@ private:
 | 
				
			||||||
	std::unique_ptr<Lottie::SinglePlayer> _lottie;
 | 
						std::unique_ptr<Lottie::SinglePlayer> _lottie;
 | 
				
			||||||
	ClickHandlerPtr _link;
 | 
						ClickHandlerPtr _link;
 | 
				
			||||||
	QSize _size;
 | 
						QSize _size;
 | 
				
			||||||
 | 
						QImage _lastDiceFrame;
 | 
				
			||||||
 | 
						int _diceIndex = -1;
 | 
				
			||||||
	mutable bool _lottieOncePlayed = false;
 | 
						mutable bool _lottieOncePlayed = false;
 | 
				
			||||||
 | 
						mutable bool _atTheEnd = false;
 | 
				
			||||||
 | 
						mutable bool _nextLastDiceFrame = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rpl::lifetime _lifetime;
 | 
						rpl::lifetime _lifetime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "core/changelogs.h"
 | 
					#include "core/changelogs.h"
 | 
				
			||||||
#include "main/main_account.h"
 | 
					#include "main/main_account.h"
 | 
				
			||||||
#include "chat_helpers/stickers_emoji_pack.h"
 | 
					#include "chat_helpers/stickers_emoji_pack.h"
 | 
				
			||||||
 | 
					#include "chat_helpers/stickers_dice_pack.h"
 | 
				
			||||||
#include "storage/file_download.h"
 | 
					#include "storage/file_download.h"
 | 
				
			||||||
#include "storage/download_manager_mtproto.h"
 | 
					#include "storage/download_manager_mtproto.h"
 | 
				
			||||||
#include "storage/file_upload.h"
 | 
					#include "storage/file_upload.h"
 | 
				
			||||||
| 
						 | 
					@ -56,6 +57,7 @@ Session::Session(
 | 
				
			||||||
, _data(std::make_unique<Data::Session>(this))
 | 
					, _data(std::make_unique<Data::Session>(this))
 | 
				
			||||||
, _user(_data->processUser(user))
 | 
					, _user(_data->processUser(user))
 | 
				
			||||||
, _emojiStickersPack(std::make_unique<Stickers::EmojiPack>(this))
 | 
					, _emojiStickersPack(std::make_unique<Stickers::EmojiPack>(this))
 | 
				
			||||||
 | 
					, _diceStickersPack(std::make_unique<Stickers::DicePack>(this))
 | 
				
			||||||
, _changelogs(Core::Changelogs::Create(this))
 | 
					, _changelogs(Core::Changelogs::Create(this))
 | 
				
			||||||
, _supportHelper(Support::Helper::Create(this)) {
 | 
					, _supportHelper(Support::Helper::Create(this)) {
 | 
				
			||||||
	Core::App().passcodeLockChanges(
 | 
						Core::App().passcodeLockChanges(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,6 +46,7 @@ class Instance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Stickers {
 | 
					namespace Stickers {
 | 
				
			||||||
class EmojiPack;
 | 
					class EmojiPack;
 | 
				
			||||||
 | 
					class DicePack;
 | 
				
			||||||
} // namespace Stickers;
 | 
					} // namespace Stickers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Core {
 | 
					namespace Core {
 | 
				
			||||||
| 
						 | 
					@ -89,9 +90,12 @@ public:
 | 
				
			||||||
	[[nodiscard]] Storage::Facade &storage() {
 | 
						[[nodiscard]] Storage::Facade &storage() {
 | 
				
			||||||
		return *_storage;
 | 
							return *_storage;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	[[nodiscard]] Stickers::EmojiPack &emojiStickersPack() {
 | 
						[[nodiscard]] Stickers::EmojiPack &emojiStickersPack() const {
 | 
				
			||||||
		return *_emojiStickersPack;
 | 
							return *_emojiStickersPack;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						[[nodiscard]] Stickers::DicePack &diceStickersPack() const {
 | 
				
			||||||
 | 
							return *_diceStickersPack;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] base::Observable<void> &downloaderTaskFinished();
 | 
						[[nodiscard]] base::Observable<void> &downloaderTaskFinished();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -157,6 +161,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// _emojiStickersPack depends on _data.
 | 
						// _emojiStickersPack depends on _data.
 | 
				
			||||||
	const std::unique_ptr<Stickers::EmojiPack> _emojiStickersPack;
 | 
						const std::unique_ptr<Stickers::EmojiPack> _emojiStickersPack;
 | 
				
			||||||
 | 
						const std::unique_ptr<Stickers::DicePack> _diceStickersPack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// _changelogs depends on _data, subscribes on chats loading event.
 | 
						// _changelogs depends on _data, subscribes on chats loading event.
 | 
				
			||||||
	const std::unique_ptr<Core::Changelogs> _changelogs;
 | 
						const std::unique_ptr<Core::Changelogs> _changelogs;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -967,6 +967,10 @@ void FileLoadTask::finish() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FileLoadResult *FileLoadTask::peekResult() const {
 | 
				
			||||||
 | 
						return _result.get();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FileLoadTask::removeFromAlbum() {
 | 
					void FileLoadTask::removeFromAlbum() {
 | 
				
			||||||
	if (!_album) {
 | 
						if (!_album) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -292,6 +292,8 @@ public:
 | 
				
			||||||
	void process();
 | 
						void process();
 | 
				
			||||||
	void finish();
 | 
						void finish();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FileLoadResult *peekResult() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	static bool CheckForSong(
 | 
						static bool CheckForSong(
 | 
				
			||||||
		const QString &filepath,
 | 
							const QString &filepath,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue