Minimal emoji sets support.
This commit is contained in:
		
							parent
							
								
									afc7b1da62
								
							
						
					
					
						commit
						ddd5021966
					
				
					 12 changed files with 182 additions and 49 deletions
				
			
		| 
						 | 
				
			
			@ -127,8 +127,12 @@ public:
 | 
			
		|||
 | 
			
		||||
	void archiveStickers();
 | 
			
		||||
 | 
			
		||||
	bool isMasksSet() const {
 | 
			
		||||
		return (_setFlags & SetFlag::Masks);
 | 
			
		||||
	[[nodiscard]] Data::StickersType setType() const {
 | 
			
		||||
		return (_setFlags & SetFlag::Emoji)
 | 
			
		||||
			? Data::StickersType::Emoji
 | 
			
		||||
			: (_setFlags & SetFlag::Masks)
 | 
			
		||||
			? Data::StickersType::Masks
 | 
			
		||||
			: Data::StickersType::Stickers;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	~Inner();
 | 
			
		||||
| 
						 | 
				
			
			@ -271,11 +275,14 @@ void StickerSetBox::prepare() {
 | 
			
		|||
 | 
			
		||||
	_inner->setInstalled(
 | 
			
		||||
	) | rpl::start_with_next([=](uint64 setId) {
 | 
			
		||||
		if (_inner->isMasksSet()) {
 | 
			
		||||
		if (_inner->setType() == Data::StickersType::Masks) {
 | 
			
		||||
			Ui::Toast::Show(
 | 
			
		||||
				Ui::BoxShow(this).toastParent(),
 | 
			
		||||
				tr::lng_masks_installed(tr::now));
 | 
			
		||||
		} else {
 | 
			
		||||
		} else if (_inner->setType() == Data::StickersType::Emoji) {
 | 
			
		||||
			auto &stickers = _controller->session().data().stickers();
 | 
			
		||||
			stickers.notifyEmojiSetInstalled(setId);
 | 
			
		||||
		} else if (_inner->setType() == Data::StickersType::Stickers) {
 | 
			
		||||
			auto &stickers = _controller->session().data().stickers();
 | 
			
		||||
			stickers.notifyStickerSetInstalled(setId);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -289,15 +296,18 @@ void StickerSetBox::prepare() {
 | 
			
		|||
 | 
			
		||||
	_inner->setArchived(
 | 
			
		||||
	) | rpl::start_with_next([=](uint64 setId) {
 | 
			
		||||
		const auto isMasks = _inner->isMasksSet();
 | 
			
		||||
		const auto type = _inner->setType();
 | 
			
		||||
		if (type == Data::StickersType::Emoji) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Ui::Toast::Show(
 | 
			
		||||
			Ui::BoxShow(this).toastParent(),
 | 
			
		||||
			isMasks
 | 
			
		||||
			(type == Data::StickersType::Masks)
 | 
			
		||||
				? tr::lng_masks_has_been_archived(tr::now)
 | 
			
		||||
				: tr::lng_stickers_has_been_archived(tr::now));
 | 
			
		||||
 | 
			
		||||
		auto &order = isMasks
 | 
			
		||||
		auto &order = (type == Data::StickersType::Masks)
 | 
			
		||||
			? _controller->session().data().stickers().maskSetsOrderRef()
 | 
			
		||||
			: _controller->session().data().stickers().setsOrderRef();
 | 
			
		||||
		const auto index = order.indexOf(setId);
 | 
			
		||||
| 
						 | 
				
			
			@ -305,7 +315,7 @@ void StickerSetBox::prepare() {
 | 
			
		|||
			order.removeAt(index);
 | 
			
		||||
 | 
			
		||||
			auto &local = _controller->session().local();
 | 
			
		||||
			if (isMasks) {
 | 
			
		||||
			if (type == Data::StickersType::Masks) {
 | 
			
		||||
				local.writeInstalledMasks();
 | 
			
		||||
				local.writeArchivedMasks();
 | 
			
		||||
			} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -352,11 +362,11 @@ void StickerSetBox::updateTitleAndButtons() {
 | 
			
		|||
void StickerSetBox::updateButtons() {
 | 
			
		||||
	clearButtons();
 | 
			
		||||
	if (_inner->loaded()) {
 | 
			
		||||
		const auto isMasks = _inner->isMasksSet();
 | 
			
		||||
		const auto type = _inner->setType();
 | 
			
		||||
		if (_inner->notInstalled()) {
 | 
			
		||||
			auto addText = isMasks
 | 
			
		||||
			auto addText = (type == Data::StickersType::Masks)
 | 
			
		||||
				? tr::lng_stickers_add_masks()
 | 
			
		||||
				: tr::lng_stickers_add_pack();
 | 
			
		||||
				: tr::lng_stickers_add_pack(); // #TODO emoji
 | 
			
		||||
			addButton(std::move(addText), [=] { addStickers(); });
 | 
			
		||||
			addButton(tr::lng_cancel(), [=] { closeBox(); });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -376,9 +386,9 @@ void StickerSetBox::updateButtons() {
 | 
			
		|||
						top,
 | 
			
		||||
						st::popupMenuWithIcons);
 | 
			
		||||
					(*menu)->addAction(
 | 
			
		||||
						(isMasks
 | 
			
		||||
						((type == Data::StickersType::Masks)
 | 
			
		||||
							? tr::lng_stickers_share_masks
 | 
			
		||||
							: tr::lng_stickers_share_pack)(tr::now),
 | 
			
		||||
							: tr::lng_stickers_share_pack)(tr::now), // #TODO emoji
 | 
			
		||||
						share,
 | 
			
		||||
						&st::menuIconShare);
 | 
			
		||||
					(*menu)->popup(QCursor::pos());
 | 
			
		||||
| 
						 | 
				
			
			@ -394,9 +404,9 @@ void StickerSetBox::updateButtons() {
 | 
			
		|||
					Ui::BoxShow(this).toastParent(),
 | 
			
		||||
					tr::lng_stickers_copied(tr::now));
 | 
			
		||||
			};
 | 
			
		||||
			auto shareText = isMasks
 | 
			
		||||
			auto shareText = (type == Data::StickersType::Masks)
 | 
			
		||||
				? tr::lng_stickers_share_masks()
 | 
			
		||||
				: tr::lng_stickers_share_pack();
 | 
			
		||||
				: tr::lng_stickers_share_pack(); // #TODO emoji
 | 
			
		||||
			addButton(std::move(shareText), std::move(share));
 | 
			
		||||
			addButton(tr::lng_cancel(), [=] { closeBox(); });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -412,9 +422,9 @@ void StickerSetBox::updateButtons() {
 | 
			
		|||
						top,
 | 
			
		||||
						st::popupMenuWithIcons);
 | 
			
		||||
					(*menu)->addAction(
 | 
			
		||||
						isMasks
 | 
			
		||||
						(type == Data::StickersType::Masks)
 | 
			
		||||
							? tr::lng_masks_archive_pack(tr::now)
 | 
			
		||||
							: tr::lng_stickers_archive_pack(tr::now),
 | 
			
		||||
							: tr::lng_stickers_archive_pack(tr::now), // #TODO emoji
 | 
			
		||||
						archive,
 | 
			
		||||
						&st::menuIconArchive);
 | 
			
		||||
					(*menu)->popup(QCursor::pos());
 | 
			
		||||
| 
						 | 
				
			
			@ -599,15 +609,15 @@ void StickerSetBox::Inner::installDone(
 | 
			
		|||
		const MTPmessages_StickerSetInstallResult &result) {
 | 
			
		||||
	auto &stickers = _controller->session().data().stickers();
 | 
			
		||||
	auto &sets = stickers.setsRef();
 | 
			
		||||
	const auto isMasks = isMasksSet();
 | 
			
		||||
	const auto type = setType();
 | 
			
		||||
 | 
			
		||||
	const bool wasArchived = (_setFlags & SetFlag::Archived);
 | 
			
		||||
	if (wasArchived) {
 | 
			
		||||
		const auto index = (isMasks
 | 
			
		||||
	if (wasArchived && type != Data::StickersType::Emoji) {
 | 
			
		||||
		const auto index = ((type == Data::StickersType::Masks)
 | 
			
		||||
			? stickers.archivedMaskSetsOrderRef()
 | 
			
		||||
			: stickers.archivedSetsOrderRef()).indexOf(_setId);
 | 
			
		||||
		if (index >= 0) {
 | 
			
		||||
			(isMasks
 | 
			
		||||
			((type == Data::StickersType::Masks)
 | 
			
		||||
				? stickers.archivedMaskSetsOrderRef()
 | 
			
		||||
				: stickers.archivedSetsOrderRef()).removeAt(index);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -638,7 +648,9 @@ void StickerSetBox::Inner::installDone(
 | 
			
		|||
	set->stickers = _pack;
 | 
			
		||||
	set->emoji = _emoji;
 | 
			
		||||
 | 
			
		||||
	auto &order = isMasks
 | 
			
		||||
	auto &order = (type == Data::StickersType::Emoji)
 | 
			
		||||
		? stickers.emojiSetsOrderRef()
 | 
			
		||||
		: (type == Data::StickersType::Masks)
 | 
			
		||||
		? stickers.maskSetsOrderRef()
 | 
			
		||||
		: stickers.setsOrderRef();
 | 
			
		||||
	const auto insertAtIndex = 0, currentIndex = int(order.indexOf(_setId));
 | 
			
		||||
| 
						 | 
				
			
			@ -668,14 +680,16 @@ void StickerSetBox::Inner::installDone(
 | 
			
		|||
			result.c_messages_stickerSetInstallResultArchive());
 | 
			
		||||
	} else {
 | 
			
		||||
		auto &storage = _controller->session().local();
 | 
			
		||||
		if (wasArchived) {
 | 
			
		||||
			if (isMasks) {
 | 
			
		||||
		if (wasArchived && type != Data::StickersType::Emoji) {
 | 
			
		||||
			if (type == Data::StickersType::Masks) {
 | 
			
		||||
				storage.writeArchivedMasks();
 | 
			
		||||
			} else {
 | 
			
		||||
				storage.writeArchivedStickers();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (isMasks) {
 | 
			
		||||
		if (type == Data::StickersType::Emoji) {
 | 
			
		||||
			storage.writeInstalledCustomEmoji();
 | 
			
		||||
		} else if (type == Data::StickersType::Masks) {
 | 
			
		||||
			storage.writeInstalledMasks();
 | 
			
		||||
		} else {
 | 
			
		||||
			storage.writeInstalledStickers();
 | 
			
		||||
| 
						 | 
				
			
			@ -723,7 +737,9 @@ void StickerSetBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
 | 
			
		|||
	}
 | 
			
		||||
	_previewTimer.cancel();
 | 
			
		||||
	const auto index = stickerFromGlobalPos(e->globalPos());
 | 
			
		||||
	if (index < 0 || index >= _pack.size() || isMasksSet()) {
 | 
			
		||||
	if (index < 0
 | 
			
		||||
		|| index >= _pack.size()
 | 
			
		||||
		|| setType() != Data::StickersType::Stickers) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	send(_pack[index], {});
 | 
			
		||||
| 
						 | 
				
			
			@ -786,7 +802,7 @@ void StickerSetBox::Inner::contextMenuEvent(QContextMenuEvent *e) {
 | 
			
		|||
 | 
			
		||||
void StickerSetBox::Inner::updateSelected() {
 | 
			
		||||
	auto selected = stickerFromGlobalPos(QCursor::pos());
 | 
			
		||||
	setSelected(isMasksSet() ? -1 : selected);
 | 
			
		||||
	setSelected(setType() != Data::StickersType::Stickers ? -1 : selected);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void StickerSetBox::Inner::setSelected(int selected) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1001,13 +1001,13 @@ void StickersBox::saveChanges() {
 | 
			
		|||
		session().api().saveStickerSets(
 | 
			
		||||
			installed->getOrder(),
 | 
			
		||||
			installed->getRemovedSets(),
 | 
			
		||||
			false);
 | 
			
		||||
			Data::StickersType::Stickers);
 | 
			
		||||
	}
 | 
			
		||||
	if (masks) {
 | 
			
		||||
		session().api().saveStickerSets(
 | 
			
		||||
			masks->getOrder(),
 | 
			
		||||
			masks->getRemovedSets(),
 | 
			
		||||
			true);
 | 
			
		||||
			Data::StickersType::Masks);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1024,7 +1024,7 @@ void EmojiListWidget::refreshCustom() {
 | 
			
		|||
	auto searchFromIndex = 0;
 | 
			
		||||
	auto old = base::take(_custom);
 | 
			
		||||
	const auto owner = &controller()->session().data();
 | 
			
		||||
	const auto &order = owner->stickers().setsOrder();
 | 
			
		||||
	const auto &order = owner->stickers().emojiSetsOrder();
 | 
			
		||||
	const auto &sets = owner->stickers().sets();
 | 
			
		||||
	for (const auto setId : order) {
 | 
			
		||||
		auto it = sets.find(setId);
 | 
			
		||||
| 
						 | 
				
			
			@ -1158,8 +1158,8 @@ void EmojiListWidget::showEmojiSection(Section section) {
 | 
			
		|||
	refreshRecent();
 | 
			
		||||
 | 
			
		||||
	auto y = 0;
 | 
			
		||||
	enumerateSections([&y, sectionForSearch = section](const SectionInfo &info) {
 | 
			
		||||
		if (static_cast<Section>(info.section) == sectionForSearch) {
 | 
			
		||||
	enumerateSections([&](const SectionInfo &info) {
 | 
			
		||||
		if (static_cast<Section>(info.section) == section) {
 | 
			
		||||
			y = info.top;
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1172,6 +1172,28 @@ void EmojiListWidget::showEmojiSection(Section section) {
 | 
			
		|||
	update();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EmojiListWidget::showCustomSet(uint64 setId) {
 | 
			
		||||
	clearSelection();
 | 
			
		||||
 | 
			
		||||
	refreshCustom();
 | 
			
		||||
 | 
			
		||||
	auto y = 0;
 | 
			
		||||
	enumerateSections([&](const SectionInfo &info) {
 | 
			
		||||
		if (info.section >= kEmojiSectionCount) {
 | 
			
		||||
			if (_custom[info.section - kEmojiSectionCount].id == setId) {
 | 
			
		||||
				y = info.top;
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	});
 | 
			
		||||
	scrollTo(y);
 | 
			
		||||
 | 
			
		||||
	_lastMousePos = QCursor::pos();
 | 
			
		||||
 | 
			
		||||
	update();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tr::phrase<> EmojiCategoryTitle(int index) {
 | 
			
		||||
	switch (index) {
 | 
			
		||||
	case 1: return tr::lng_emoji_category1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,6 +53,8 @@ public:
 | 
			
		|||
	void showEmojiSection(Section section);
 | 
			
		||||
	[[nodiscard]] Section currentSection(int yOffset) const;
 | 
			
		||||
 | 
			
		||||
	void showCustomSet(uint64 setId);
 | 
			
		||||
 | 
			
		||||
	// Ui::AbstractTooltipShower interface.
 | 
			
		||||
	QString tooltipText() const override;
 | 
			
		||||
	QPoint tooltipPos() const override;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -401,6 +401,15 @@ TabbedSelector::TabbedSelector(
 | 
			
		|||
			refreshStickers();
 | 
			
		||||
		}, lifetime());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (hasEmojiTab()) {
 | 
			
		||||
		session().data().stickers().emojiSetInstalled(
 | 
			
		||||
		) | rpl::start_with_next([=](uint64 setId) {
 | 
			
		||||
			_tabsSlider->setActiveSection(indexByType(SelectorTab::Emoji));
 | 
			
		||||
			emoji()->showCustomSet(setId);
 | 
			
		||||
			_showRequests.fire({});
 | 
			
		||||
		}, lifetime());
 | 
			
		||||
	}
 | 
			
		||||
	//setAttribute(Qt::WA_AcceptTouchEvents);
 | 
			
		||||
	setAttribute(Qt::WA_OpaquePaintEvent, false);
 | 
			
		||||
	showAll();
 | 
			
		||||
| 
						 | 
				
			
			@ -772,6 +781,9 @@ void TabbedSelector::showStarted() {
 | 
			
		|||
	if (hasMasksTab()) {
 | 
			
		||||
		session().api().updateMasks();
 | 
			
		||||
	}
 | 
			
		||||
	if (hasEmojiTab()) {
 | 
			
		||||
		session().api().updateCustomEmoji();
 | 
			
		||||
	}
 | 
			
		||||
	currentTab()->widget()->refreshRecent();
 | 
			
		||||
	currentTab()->widget()->preloadImages();
 | 
			
		||||
	_a_slide.stop();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ bool ShowStickerSet(
 | 
			
		|||
	Core::App().hideMediaView();
 | 
			
		||||
	controller->show(Box<StickerSetBox>(
 | 
			
		||||
		controller,
 | 
			
		||||
		StickerSetIdentifier{ .shortName = match->captured(1) }));
 | 
			
		||||
		StickerSetIdentifier{ .shortName = match->captured(2) }));
 | 
			
		||||
	controller->window().activate();
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -781,7 +781,7 @@ const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
 | 
			
		|||
			JoinGroupByHash
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			qsl("^addstickers/?\\?set=([a-zA-Z0-9\\.\\_]+)(&|$)"),
 | 
			
		||||
			qsl("^(addstickers|addemoji)/?\\?set=([a-zA-Z0-9\\.\\_]+)(&|$)"),
 | 
			
		||||
			ShowStickerSet
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -885,8 +885,8 @@ QString TryConvertUrlToLocal(QString url) {
 | 
			
		|||
			return qsl("tg://resolve?phone=") + phoneMatch->captured(1) + (params.isEmpty() ? QString() : '&' + params);
 | 
			
		||||
		} else if (auto joinChatMatch = regex_match(qsl("^(joinchat/|\\+|\\%20)([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"), query, matchOptions)) {
 | 
			
		||||
			return qsl("tg://join?invite=") + url_encode(joinChatMatch->captured(2));
 | 
			
		||||
		} else if (auto stickerSetMatch = regex_match(qsl("^addstickers/([a-zA-Z0-9\\.\\_]+)(\\?|$)"), query, matchOptions)) {
 | 
			
		||||
			return qsl("tg://addstickers?set=") + url_encode(stickerSetMatch->captured(1));
 | 
			
		||||
		} else if (auto stickerSetMatch = regex_match(qsl("^(addstickers|addemoji)/([a-zA-Z0-9\\.\\_]+)(\\?|$)"), query, matchOptions)) {
 | 
			
		||||
			return qsl("tg://") + stickerSetMatch->captured(1) + "?set=" + url_encode(stickerSetMatch->captured(2));
 | 
			
		||||
		} else if (auto themeMatch = regex_match(qsl("^addtheme/([a-zA-Z0-9\\.\\_]+)(\\?|$)"), query, matchOptions)) {
 | 
			
		||||
			return qsl("tg://addtheme?slug=") + url_encode(themeMatch->captured(1));
 | 
			
		||||
		} else if (auto languageMatch = regex_match(qsl("^setlanguage/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"), query, matchOptions)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -178,6 +178,14 @@ rpl::producer<uint64> Stickers::stickerSetInstalled() const {
 | 
			
		|||
	return _stickerSetInstalled.events();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Stickers::notifyEmojiSetInstalled(uint64 setId) {
 | 
			
		||||
	_emojiSetInstalled.fire(std::move(setId));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
rpl::producer<uint64> Stickers::emojiSetInstalled() const {
 | 
			
		||||
	return _emojiSetInstalled.events();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Stickers::incrementSticker(not_null<DocumentData*> document) {
 | 
			
		||||
	if (!document->sticker() || !document->sticker()->set) {
 | 
			
		||||
		return;
 | 
			
		||||
| 
						 | 
				
			
			@ -662,28 +670,42 @@ void Stickers::setFaved(
 | 
			
		|||
void Stickers::setsReceived(
 | 
			
		||||
		const QVector<MTPStickerSet> &data,
 | 
			
		||||
		uint64 hash) {
 | 
			
		||||
	setsOrMasksReceived(data, hash, false);
 | 
			
		||||
	somethingReceived(data, hash, StickersType::Stickers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Stickers::masksReceived(
 | 
			
		||||
		const QVector<MTPStickerSet> &data,
 | 
			
		||||
		uint64 hash) {
 | 
			
		||||
	setsOrMasksReceived(data, hash, true);
 | 
			
		||||
	somethingReceived(data, hash, StickersType::Masks);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Stickers::setsOrMasksReceived(
 | 
			
		||||
void Stickers::emojiReceived(
 | 
			
		||||
		const QVector<MTPStickerSet> &data,
 | 
			
		||||
		uint64 hash) {
 | 
			
		||||
	somethingReceived(data, hash, StickersType::Emoji);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Stickers::somethingReceived(
 | 
			
		||||
		const QVector<MTPStickerSet> &data,
 | 
			
		||||
		uint64 hash,
 | 
			
		||||
		bool masks) {
 | 
			
		||||
	auto &setsOrder = masks ? maskSetsOrderRef() : setsOrderRef();
 | 
			
		||||
		StickersType type) {
 | 
			
		||||
	auto &setsOrder = (type == StickersType::Emoji)
 | 
			
		||||
		? emojiSetsOrderRef()
 | 
			
		||||
		: (type == StickersType::Masks)
 | 
			
		||||
		? maskSetsOrderRef()
 | 
			
		||||
		: setsOrderRef();
 | 
			
		||||
	setsOrder.clear();
 | 
			
		||||
 | 
			
		||||
	auto &sets = setsRef();
 | 
			
		||||
	QMap<uint64, uint64> setsToRequest;
 | 
			
		||||
	for (auto &[id, set] : sets) {
 | 
			
		||||
		const auto archived = !!(set->flags & SetFlag::Archived);
 | 
			
		||||
		const auto maskset = !!(set->flags & SetFlag::Masks);
 | 
			
		||||
		if (!archived && (masks == maskset)) {
 | 
			
		||||
		const auto setType = !!(set->flags & SetFlag::Emoji)
 | 
			
		||||
			? StickersType::Emoji
 | 
			
		||||
			: !!(set->flags & SetFlag::Masks)
 | 
			
		||||
			? StickersType::Masks
 | 
			
		||||
			: StickersType::Stickers;
 | 
			
		||||
		if (!archived && (type == setType)) {
 | 
			
		||||
			// Mark for removing.
 | 
			
		||||
			set->flags &= ~SetFlag::Installed;
 | 
			
		||||
			set->installDate = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -736,7 +758,9 @@ void Stickers::setsOrMasksReceived(
 | 
			
		|||
		api.requestStickerSets();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (masks) {
 | 
			
		||||
	if (type == StickersType::Emoji) {
 | 
			
		||||
		session().local().writeInstalledCustomEmoji();
 | 
			
		||||
	} else if (type == StickersType::Masks) {
 | 
			
		||||
		session().local().writeInstalledMasks();
 | 
			
		||||
	} else {
 | 
			
		||||
		session().local().writeInstalledStickers();
 | 
			
		||||
| 
						 | 
				
			
			@ -745,12 +769,18 @@ void Stickers::setsOrMasksReceived(
 | 
			
		|||
		session().saveSettings();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const auto counted = masks
 | 
			
		||||
	const auto counted = (type == StickersType::Emoji)
 | 
			
		||||
		? Api::CountCustomEmojiHash(&session())
 | 
			
		||||
		: (type == StickersType::Masks)
 | 
			
		||||
		? Api::CountMasksHash(&session())
 | 
			
		||||
		: Api::CountStickersHash(&session());
 | 
			
		||||
	if (counted != hash) {
 | 
			
		||||
		LOG(("API Error: received %1 hash %2 while counted hash is %3"
 | 
			
		||||
			).arg(masks ? "masks" : "stickers"
 | 
			
		||||
			).arg((type == StickersType::Emoji)
 | 
			
		||||
				? "custom-emoji"
 | 
			
		||||
				: (type == StickersType::Masks)
 | 
			
		||||
				? "masks"
 | 
			
		||||
				: "stickers"
 | 
			
		||||
			).arg(hash
 | 
			
		||||
			).arg(counted));
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,6 +73,8 @@ public:
 | 
			
		|||
	[[nodiscard]] rpl::producer<> savedGifsUpdated() const;
 | 
			
		||||
	void notifyStickerSetInstalled(uint64 setId);
 | 
			
		||||
	[[nodiscard]] rpl::producer<uint64> stickerSetInstalled() const;
 | 
			
		||||
	void notifyEmojiSetInstalled(uint64 setId);
 | 
			
		||||
	[[nodiscard]] rpl::producer<uint64> emojiSetInstalled() const;
 | 
			
		||||
 | 
			
		||||
	void incrementSticker(not_null<DocumentData*> document);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -263,7 +265,7 @@ private:
 | 
			
		|||
		StickersPack &&pack,
 | 
			
		||||
		const std::vector<TimeId> &&dates,
 | 
			
		||||
		const QVector<MTPStickerPack> &packs);
 | 
			
		||||
	void setsOrMasksOrEmojiReceived(
 | 
			
		||||
	void somethingReceived(
 | 
			
		||||
		const QVector<MTPStickerSet> &data,
 | 
			
		||||
		uint64 hash,
 | 
			
		||||
		StickersType type);
 | 
			
		||||
| 
						 | 
				
			
			@ -273,6 +275,7 @@ private:
 | 
			
		|||
	rpl::event_stream<Recent> _recentUpdated;
 | 
			
		||||
	rpl::event_stream<> _savedGifsUpdated;
 | 
			
		||||
	rpl::event_stream<uint64> _stickerSetInstalled;
 | 
			
		||||
	rpl::event_stream<uint64> _emojiSetInstalled;
 | 
			
		||||
	crl::time _lastUpdate = 0;
 | 
			
		||||
	crl::time _lastRecentUpdate = 0;
 | 
			
		||||
	crl::time _lastFavedUpdate = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -155,6 +155,7 @@ Session::Session(
 | 
			
		|||
		// So they can't be called during Main::Session construction.
 | 
			
		||||
		local().readInstalledStickers();
 | 
			
		||||
		local().readInstalledMasks();
 | 
			
		||||
		local().readInstalledCustomEmoji();
 | 
			
		||||
		local().readFeaturedStickers();
 | 
			
		||||
		local().readRecentStickers();
 | 
			
		||||
		local().readRecentMasks();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -144,8 +144,7 @@ DocumentData *Document::readFromStreamHelper(
 | 
			
		|||
					MTP_string(alt),
 | 
			
		||||
					MTP_inputStickerSetID(
 | 
			
		||||
						MTP_long(info->setId),
 | 
			
		||||
						MTP_long(info->accessHash)),
 | 
			
		||||
					MTPMaskCoords()));
 | 
			
		||||
						MTP_long(info->accessHash))));
 | 
			
		||||
			} break;
 | 
			
		||||
			case StickerSetTypeEmpty:
 | 
			
		||||
			default: {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,6 +84,7 @@ enum { // Local Storage Keys
 | 
			
		|||
	lskBackgroundOld = 0x14, // no data
 | 
			
		||||
	lskSelfSerialized = 0x15, // serialized self
 | 
			
		||||
	lskMasksKeys = 0x16, // no data
 | 
			
		||||
	lskCustomEmojiKeys = 0x17, // no data
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
auto EmptyMessageDraftSources()
 | 
			
		||||
| 
						 | 
				
			
			@ -203,6 +204,9 @@ base::flat_set<QString> Account::collectGoodNames() const {
 | 
			
		|||
		_installedMasksKey,
 | 
			
		||||
		_recentMasksKey,
 | 
			
		||||
		_archivedMasksKey,
 | 
			
		||||
		_installedCustomEmojiKey,
 | 
			
		||||
		_recentCustomEmojiKey,
 | 
			
		||||
		_archivedCustomEmojiKey,
 | 
			
		||||
	};
 | 
			
		||||
	auto result = base::flat_set<QString>{
 | 
			
		||||
		"map0",
 | 
			
		||||
| 
						 | 
				
			
			@ -284,6 +288,7 @@ Account::ReadMapResult Account::readMapWith(
 | 
			
		|||
	quint64 recentStickersKeyOld = 0;
 | 
			
		||||
	quint64 installedStickersKey = 0, featuredStickersKey = 0, recentStickersKey = 0, favedStickersKey = 0, archivedStickersKey = 0;
 | 
			
		||||
	quint64 installedMasksKey = 0, recentMasksKey = 0, archivedMasksKey = 0;
 | 
			
		||||
	quint64 installedCustomEmojiKey = 0, recentCustomEmojiKey = 0, archivedCustomEmojiKey = 0;
 | 
			
		||||
	quint64 savedGifsKey = 0;
 | 
			
		||||
	quint64 legacyBackgroundKeyDay = 0, legacyBackgroundKeyNight = 0;
 | 
			
		||||
	quint64 userSettingsKey = 0, recentHashtagsAndBotsKey = 0, exportSettingsKey = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -386,6 +391,12 @@ Account::ReadMapResult Account::readMapWith(
 | 
			
		|||
				>> recentMasksKey
 | 
			
		||||
				>> archivedMasksKey;
 | 
			
		||||
		} break;
 | 
			
		||||
		case lskCustomEmojiKeys: {
 | 
			
		||||
			map.stream
 | 
			
		||||
				>> installedCustomEmojiKey
 | 
			
		||||
				>> recentCustomEmojiKey
 | 
			
		||||
				>> archivedCustomEmojiKey;
 | 
			
		||||
		} break;
 | 
			
		||||
		default:
 | 
			
		||||
			LOG(("App Error: unknown key type in encrypted map: %1").arg(keyType));
 | 
			
		||||
			return ReadMapResult::Failed;
 | 
			
		||||
| 
						 | 
				
			
			@ -413,6 +424,9 @@ Account::ReadMapResult Account::readMapWith(
 | 
			
		|||
	_installedMasksKey = installedMasksKey;
 | 
			
		||||
	_recentMasksKey = recentMasksKey;
 | 
			
		||||
	_archivedMasksKey = archivedMasksKey;
 | 
			
		||||
	_installedCustomEmojiKey = installedCustomEmojiKey;
 | 
			
		||||
	_recentCustomEmojiKey = recentCustomEmojiKey;
 | 
			
		||||
	_archivedCustomEmojiKey = archivedCustomEmojiKey;
 | 
			
		||||
	_legacyBackgroundKeyDay = legacyBackgroundKeyDay;
 | 
			
		||||
	_legacyBackgroundKeyNight = legacyBackgroundKeyNight;
 | 
			
		||||
	_settingsKey = userSettingsKey;
 | 
			
		||||
| 
						 | 
				
			
			@ -520,6 +534,9 @@ void Account::writeMap() {
 | 
			
		|||
	if (_installedMasksKey || _recentMasksKey || _archivedMasksKey) {
 | 
			
		||||
		mapSize += sizeof(quint32) + 3 * sizeof(quint64);
 | 
			
		||||
	}
 | 
			
		||||
	if (_installedCustomEmojiKey || _recentCustomEmojiKey || _archivedCustomEmojiKey) {
 | 
			
		||||
		mapSize += sizeof(quint32) + 3 * sizeof(quint64);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	EncryptedDescriptor mapData(mapSize);
 | 
			
		||||
	if (!self.isEmpty()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -572,6 +589,13 @@ void Account::writeMap() {
 | 
			
		|||
			<< quint64(_recentMasksKey)
 | 
			
		||||
			<< quint64(_archivedMasksKey);
 | 
			
		||||
	}
 | 
			
		||||
	if (_installedCustomEmojiKey || _recentCustomEmojiKey || _archivedCustomEmojiKey) {
 | 
			
		||||
		mapData.stream << quint32(lskCustomEmojiKeys);
 | 
			
		||||
		mapData.stream
 | 
			
		||||
			<< quint64(_installedCustomEmojiKey)
 | 
			
		||||
			<< quint64(_recentCustomEmojiKey)
 | 
			
		||||
			<< quint64(_archivedCustomEmojiKey);
 | 
			
		||||
	}
 | 
			
		||||
	map.writeEncrypted(mapData, _localKey);
 | 
			
		||||
 | 
			
		||||
	_mapChanged = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -593,6 +617,9 @@ void Account::reset() {
 | 
			
		|||
	_installedMasksKey = 0;
 | 
			
		||||
	_recentMasksKey = 0;
 | 
			
		||||
	_archivedMasksKey = 0;
 | 
			
		||||
	_installedCustomEmojiKey = 0;
 | 
			
		||||
	_recentCustomEmojiKey = 0;
 | 
			
		||||
	_archivedCustomEmojiKey = 0;
 | 
			
		||||
	_legacyBackgroundKeyDay = _legacyBackgroundKeyNight = 0;
 | 
			
		||||
	_settingsKey = _recentHashtagsAndBotsKey = _exportSettingsKey = 0;
 | 
			
		||||
	_oldMapVersion = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -2091,6 +2118,17 @@ void Account::writeRecentMasks() {
 | 
			
		|||
	}, Data::StickersSetsOrder());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Account::writeInstalledCustomEmoji() {
 | 
			
		||||
	using SetFlag = Data::StickersSetFlag;
 | 
			
		||||
 | 
			
		||||
	writeStickerSets(_installedCustomEmojiKey, [](const Data::StickersSet &set) {
 | 
			
		||||
		if (!(set.flags & SetFlag::Emoji) || set.stickers.isEmpty()) {
 | 
			
		||||
			return StickerSetCheckResult::Skip;
 | 
			
		||||
		}
 | 
			
		||||
		return StickerSetCheckResult::Write;
 | 
			
		||||
	}, _owner->session().data().stickers().emojiSetsOrder());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Account::importOldRecentStickers() {
 | 
			
		||||
	using SetFlag = Data::StickersSetFlag;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2283,6 +2321,13 @@ void Account::readInstalledMasks() {
 | 
			
		|||
		Data::StickersSetFlag::Installed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Account::readInstalledCustomEmoji() {
 | 
			
		||||
	readStickerSets(
 | 
			
		||||
		_installedCustomEmojiKey,
 | 
			
		||||
		&_owner->session().data().stickers().emojiSetsOrderRef(),
 | 
			
		||||
		Data::StickersSetFlag::Installed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Account::writeSavedGifs() {
 | 
			
		||||
	const auto &saved = _owner->session().data().stickers().savedGifs();
 | 
			
		||||
	if (saved.isEmpty()) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -286,6 +286,9 @@ private:
 | 
			
		|||
	FileKey _exportSettingsKey = 0;
 | 
			
		||||
	FileKey _installedMasksKey = 0;
 | 
			
		||||
	FileKey _recentMasksKey = 0;
 | 
			
		||||
	FileKey _installedCustomEmojiKey = 0;
 | 
			
		||||
	FileKey _recentCustomEmojiKey = 0;
 | 
			
		||||
	FileKey _archivedCustomEmojiKey = 0;
 | 
			
		||||
 | 
			
		||||
	qint64 _cacheTotalSizeLimit = 0;
 | 
			
		||||
	qint64 _cacheBigFileTotalSizeLimit = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue