diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt
index ce42a119f..66b712eb4 100644
--- a/Telegram/CMakeLists.txt
+++ b/Telegram/CMakeLists.txt
@@ -422,6 +422,8 @@ PRIVATE
     data/data_document.h
     data/data_document_media.cpp
     data/data_document_media.h
+    data/data_document_resolver.cpp
+    data/data_document_resolver.h
     data/data_drafts.cpp
     data/data_drafts.h
     data/data_folder.cpp
diff --git a/Telegram/SourceFiles/boxes/background_preview_box.cpp b/Telegram/SourceFiles/boxes/background_preview_box.cpp
index a3d667bfb..cf1af6627 100644
--- a/Telegram/SourceFiles/boxes/background_preview_box.cpp
+++ b/Telegram/SourceFiles/boxes/background_preview_box.cpp
@@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "data/data_user.h"
 #include "data/data_document.h"
 #include "data/data_document_media.h"
+#include "data/data_document_resolver.h"
 #include "data/data_file_origin.h"
 #include "base/unixtime.h"
 #include "boxes/confirm_box.h"
diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp
index a687acc1f..c09ea3d2e 100644
--- a/Telegram/SourceFiles/data/data_document.cpp
+++ b/Telegram/SourceFiles/data/data_document.cpp
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 */
 #include "data/data_document.h"
 
+#include "data/data_document_resolver.h"
 #include "data/data_session.h"
 #include "data/data_streaming.h"
 #include "data/data_document_media.h"
@@ -319,65 +320,7 @@ void DocumentOpenClickHandler::Open(
 		Data::FileOrigin origin,
 		not_null<DocumentData*> data,
 		HistoryItem *context) {
-	if (!data->date) {
-		return;
-	}
-
-	const auto media = data->createMediaView();
-	const auto openImageInApp = [&] {
-		if (data->size >= App::kImageSizeLimit) {
-			return false;
-		}
-		const auto &location = data->location(true);
-		if (!location.isEmpty() && location.accessEnable()) {
-			const auto guard = gsl::finally([&] {
-				location.accessDisable();
-			});
-			const auto path = location.name();
-			if (Core::MimeTypeForFile(path).name().startsWith("image/")
-				&& QImageReader(path).canRead()) {
-				Core::App().showDocument(data, context);
-				return true;
-			}
-		} else if (data->mimeString().startsWith("image/")
-			&& !media->bytes().isEmpty()) {
-			auto bytes = media->bytes();
-			auto buffer = QBuffer(&bytes);
-			if (QImageReader(&buffer).canRead()) {
-				Core::App().showDocument(data, context);
-				return true;
-			}
-		}
-		return false;
-	};
-	const auto &location = data->location(true);
-	if (data->isTheme() && media->loaded(true)) {
-		Core::App().showDocument(data, context);
-		location.accessDisable();
-	} else if (media->canBePlayed()) {
-		if (data->isAudioFile()
-			|| data->isVoiceMessage()
-			|| data->isVideoMessage()) {
-			const auto msgId = context ? context->fullId() : FullMsgId();
-			Media::Player::instance()->playPause({ data, msgId });
-		} else if (context
-			&& data->isAnimation()
-			&& HistoryView::Gif::CanPlayInline(data)) {
-			data->owner().requestAnimationPlayInline(context);
-		} else {
-			Core::App().showDocument(data, context);
-		}
-	} else {
-		data->saveFromDataSilent();
-		if (!openImageInApp()) {
-			if (!data->filepath(true).isEmpty()) {
-				LaunchWithWarning(&data->session(), location.name(), context);
-			} else if (data->status == FileReady
-				|| data->status == FileDownloadFailed) {
-				DocumentSaveClickHandler::Save(origin, data);
-			}
-		}
-	}
+	Data::ResolveDocument(data, context);
 }
 
 void DocumentOpenClickHandler::onClickImpl() const {
@@ -1634,126 +1577,3 @@ void DocumentData::collectLocalData(not_null<DocumentData*> local) {
 		session().local().writeFileLocation(mediaKey(), _location);
 	}
 }
-
-namespace Data {
-
-QString FileExtension(const QString &filepath) {
-	const auto reversed = ranges::views::reverse(filepath);
-	const auto last = ranges::find_first_of(reversed, ".\\/");
-	if (last == reversed.end() || *last != '.') {
-		return QString();
-	}
-	return QString(last.base(), last - reversed.begin());
-}
-
-bool IsValidMediaFile(const QString &filepath) {
-	static const auto kExtensions = [] {
-		const auto list = qsl("\
-16svx 2sf 3g2 3gp 8svx aac aaf aif aifc aiff amr amv ape asf ast au aup \
-avchd avi brstm bwf cam cdda cust dat divx drc dsh dsf dts dtshd dtsma \
-dvr-ms dwd evo f4a f4b f4p f4v fla flac flr flv gif gifv gsf gsm gym iff \
-ifo it jam la ly m1v m2p m2ts m2v m4a m4p m4v mcf mid mk3d mka mks mkv mng \
-mov mp1 mp2 mp3 mp4 minipsf mod mpc mpe mpeg mpg mpv mscz mt2 mus mxf mxl \
-niff nsf nsv off ofr ofs ogg ogv opus ots pac ps psf psf2 psflib ptb qsf \
-qt ra raw rka rm rmj rmvb roq s3m shn sib sid smi smp sol spc spx ssf svi \
-swa swf tak ts tta txm usf vgm vob voc vox vqf wav webm wma wmv wrap wtv \
-wv xm xml ym yuv").split(' ');
-		return base::flat_set<QString>(list.begin(), list.end());
-	}();
-
-	return ranges::binary_search(
-		kExtensions,
-		FileExtension(filepath).toLower());
-}
-
-bool IsExecutableName(const QString &filepath) {
-	static const auto kExtensions = [] {
-		const auto joined =
-#ifdef Q_OS_MAC
-			qsl("\
-applescript action app bin command csh osx workflow terminal url caction \
-mpkg pkg scpt scptd xhtm webarchive");
-#elif defined Q_OS_UNIX // Q_OS_MAC
-			qsl("bin csh deb desktop ksh out pet pkg pup rpm run sh shar \
-slp zsh");
-#else // Q_OS_MAC || Q_OS_UNIX
-			qsl("\
-ad ade adp app application appref-ms asp asx bas bat bin cab cdxml cer cfg \
-chi chm cmd cnt com cpl crt csh der diagcab dll drv eml exe fon fxp gadget \
-grp hlp hpj hta htt inf ini ins inx isp isu its jar jnlp job js jse key ksh \
-lnk local lua mad maf mag mam manifest maq mar mas mat mau mav maw mcf mda \
-mdb mde mdt mdw mdz mht mhtml mjs mmc mof msc msg msh msh1 msh2 msh1xml \
-msh2xml mshxml msi msp mst ops osd paf pcd phar php php3 php4 php5 php7 phps \
-php-s pht phtml pif pl plg pm pod prf prg ps1 ps2 ps1xml ps2xml psc1 psc2 \
-psd1 psm1 pssc pst py py3 pyc pyd pyi pyo pyw pywz pyz rb reg rgs scf scr \
-sct search-ms settingcontent-ms sh shb shs slk sys t tmp u3p url vb vbe vbp \
-vbs vbscript vdx vsmacros vsd vsdm vsdx vss vssm vssx vst vstm vstx vsw vsx \
-vtx website ws wsc wsf wsh xbap xll xnk xs");
-#endif // !Q_OS_MAC && !Q_OS_UNIX
-		const auto list = joined.split(' ');
-		return base::flat_set<QString>(list.begin(), list.end());
-	}();
-
-	return ranges::binary_search(
-		kExtensions,
-		FileExtension(filepath).toLower());
-}
-
-bool IsIpRevealingName(const QString &filepath) {
-	static const auto kExtensions = [] {
-		const auto joined = u"htm html svg"_q;
-		const auto list = joined.split(' ');
-		return base::flat_set<QString>(list.begin(), list.end());
-	}();
-	static const auto kMimeTypes = [] {
-		const auto joined = u"text/html image/svg+xml"_q;
-		const auto list = joined.split(' ');
-		return base::flat_set<QString>(list.begin(), list.end());
-	}();
-
-	return ranges::binary_search(
-		kExtensions,
-		FileExtension(filepath).toLower()
-	) || ranges::binary_search(
-		kMimeTypes,
-		QMimeDatabase().mimeTypeForFile(QFileInfo(filepath)).name()
-	);
-}
-
-base::binary_guard ReadImageAsync(
-		not_null<Data::DocumentMedia*> media,
-		FnMut<QImage(QImage)> postprocess,
-		FnMut<void(QImage&&)> done) {
-	auto result = base::binary_guard();
-	crl::async([
-		bytes = media->bytes(),
-		path = media->owner()->filepath(),
-		postprocess = std::move(postprocess),
-		guard = result.make_guard(),
-		callback = std::move(done)
-	]() mutable {
-		auto format = QByteArray();
-		if (bytes.isEmpty()) {
-			QFile f(path);
-			if (f.size() <= App::kImageSizeLimit
-				&& f.open(QIODevice::ReadOnly)) {
-				bytes = f.readAll();
-			}
-		}
-		auto image = bytes.isEmpty()
-			? QImage()
-			: App::readImage(bytes, &format, false, nullptr);
-		if (postprocess) {
-			image = postprocess(std::move(image));
-		}
-		crl::on_main(std::move(guard), [
-			image = std::move(image),
-			callback = std::move(callback)
-		]() mutable {
-			callback(std::move(image));
-		});
-	});
-	return result;
-}
-
-} // namespace Data
diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h
index 42eb6c2bf..92cd8ba30 100644
--- a/Telegram/SourceFiles/data/data_document.h
+++ b/Telegram/SourceFiles/data/data_document.h
@@ -438,16 +438,3 @@ QString DocumentFileNameForSave(
 	bool forceSavingAs = false,
 	const QString &already = QString(),
 	const QDir &dir = QDir());
-
-namespace Data {
-
-[[nodiscard]] QString FileExtension(const QString &filepath);
-[[nodiscard]] bool IsValidMediaFile(const QString &filepath);
-[[nodiscard]] bool IsExecutableName(const QString &filepath);
-[[nodiscard]] bool IsIpRevealingName(const QString &filepath);
-base::binary_guard ReadImageAsync(
-	not_null<Data::DocumentMedia*> media,
-	FnMut<QImage(QImage)> postprocess,
-	FnMut<void(QImage&&)> done);
-
-} // namespace Data
diff --git a/Telegram/SourceFiles/data/data_document_media.cpp b/Telegram/SourceFiles/data/data_document_media.cpp
index 4a1267e6e..33fe6d556 100644
--- a/Telegram/SourceFiles/data/data_document_media.cpp
+++ b/Telegram/SourceFiles/data/data_document_media.cpp
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "data/data_document_media.h"
 
 #include "data/data_document.h"
+#include "data/data_document_resolver.h"
 #include "data/data_session.h"
 #include "data/data_cloud_themes.h"
 #include "data/data_file_origin.h"
diff --git a/Telegram/SourceFiles/data/data_document_resolver.cpp b/Telegram/SourceFiles/data/data_document_resolver.cpp
new file mode 100644
index 000000000..720c4ecf6
--- /dev/null
+++ b/Telegram/SourceFiles/data/data_document_resolver.cpp
@@ -0,0 +1,278 @@
+/*
+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 "data/data_document_resolver.h"
+
+#include "app.h"
+#include "facades.h"
+#include "base/platform/base_platform_info.h"
+#include "boxes/confirm_box.h"
+#include "core/application.h"
+#include "core/core_settings.h"
+#include "core/mime_type.h"
+#include "data/data_document.h"
+#include "data/data_document_media.h"
+#include "data/data_file_origin.h"
+#include "data/data_session.h"
+#include "history/view/media/history_view_gif.h"
+#include "history/history.h"
+#include "history/history_item.h"
+#include "media/player/media_player_instance.h"
+#include "platform/platform_file_utilities.h"
+#include "ui/text/text_utilities.h"
+#include "window/window_controller.h"
+#include "window/window_session_controller.h"
+
+#include <QtCore/QBuffer>
+#include <QtCore/QMimeType>
+#include <QtCore/QMimeDatabase>
+
+namespace Data {
+namespace {
+
+void LaunchWithWarning(
+		// not_null<Window::Controller*> controller,
+		const QString &name,
+		HistoryItem *item) {
+	const auto isExecutable = Data::IsExecutableName(name);
+	const auto isIpReveal = Data::IsIpRevealingName(name);
+	auto &app = Core::App();
+	const auto warn = [&] {
+		if (item && item->history()->peer->isVerified()) {
+			return false;
+		}
+		return (isExecutable && app.settings().exeLaunchWarning())
+			|| (isIpReveal && app.settings().ipRevealWarning());
+	}();
+	const auto extension = '.' + Data::FileExtension(name);
+	if (Platform::IsWindows() && extension == u"."_q) {
+		// If you launch a file without extension, like "test", in case
+		// there is an executable file with the same name in this folder,
+		// like "test.bat", the executable file will be launched.
+		//
+		// Now we always force an Open With dialog box for such files.
+		crl::on_main([=] {
+			Platform::File::UnsafeShowOpenWith(name);
+		});
+		return;
+	} else if (!warn) {
+		File::Launch(name);
+		return;
+	}
+	const auto callback = [=, &app](bool checked) {
+		if (checked) {
+			if (isExecutable) {
+				app.settings().setExeLaunchWarning(false);
+			} else if (isIpReveal) {
+				app.settings().setIpRevealWarning(false);
+			}
+			app.saveSettingsDelayed();
+		}
+		File::Launch(name);
+	};
+	auto text = isExecutable
+		? tr::lng_launch_exe_warning(
+			lt_extension,
+			rpl::single(Ui::Text::Bold(extension)),
+			Ui::Text::WithEntities)
+		: tr::lng_launch_svg_warning(Ui::Text::WithEntities);
+	Ui::show(Box<ConfirmDontWarnBox>(
+		std::move(text),
+		tr::lng_launch_exe_dont_ask(tr::now),
+		(isExecutable ? tr::lng_launch_exe_sure : tr::lng_continue)(),
+		callback));
+}
+
+} // namespace
+
+QString FileExtension(const QString &filepath) {
+	const auto reversed = ranges::views::reverse(filepath);
+	const auto last = ranges::find_first_of(reversed, ".\\/");
+	if (last == reversed.end() || *last != '.') {
+		return QString();
+	}
+	return QString(last.base(), last - reversed.begin());
+}
+
+// bool IsValidMediaFile(const QString &filepath) {
+// 	static const auto kExtensions = [] {
+// 		const auto list = qsl("\
+// 16svx 2sf 3g2 3gp 8svx aac aaf aif aifc aiff amr amv ape asf ast au aup \
+// avchd avi brstm bwf cam cdda cust dat divx drc dsh dsf dts dtshd dtsma \
+// dvr-ms dwd evo f4a f4b f4p f4v fla flac flr flv gif gifv gsf gsm gym iff \
+// ifo it jam la ly m1v m2p m2ts m2v m4a m4p m4v mcf mid mk3d mka mks mkv mng \
+// mov mp1 mp2 mp3 mp4 minipsf mod mpc mpe mpeg mpg mpv mscz mt2 mus mxf mxl \
+// niff nsf nsv off ofr ofs ogg ogv opus ots pac ps psf psf2 psflib ptb qsf \
+// qt ra raw rka rm rmj rmvb roq s3m shn sib sid smi smp sol spc spx ssf svi \
+// swa swf tak ts tta txm usf vgm vob voc vox vqf wav webm wma wmv wrap wtv \
+// wv xm xml ym yuv").split(' ');
+// 		return base::flat_set<QString>(list.begin(), list.end());
+// 	}();
+
+// 	return ranges::binary_search(
+// 		kExtensions,
+// 		FileExtension(filepath).toLower());
+// }
+
+bool IsExecutableName(const QString &filepath) {
+	static const auto kExtensions = [] {
+		const auto joined =
+#ifdef Q_OS_MAC
+			qsl("\
+applescript action app bin command csh osx workflow terminal url caction \
+mpkg pkg scpt scptd xhtm webarchive");
+#elif defined Q_OS_UNIX // Q_OS_MAC
+			qsl("bin csh deb desktop ksh out pet pkg pup rpm run sh shar \
+slp zsh");
+#else // Q_OS_MAC || Q_OS_UNIX
+			qsl("\
+ad ade adp app application appref-ms asp asx bas bat bin cab cdxml cer cfg \
+chi chm cmd cnt com cpl crt csh der diagcab dll drv eml exe fon fxp gadget \
+grp hlp hpj hta htt inf ini ins inx isp isu its jar jnlp job js jse key ksh \
+lnk local lua mad maf mag mam manifest maq mar mas mat mau mav maw mcf mda \
+mdb mde mdt mdw mdz mht mhtml mjs mmc mof msc msg msh msh1 msh2 msh1xml \
+msh2xml mshxml msi msp mst ops osd paf pcd phar php php3 php4 php5 php7 phps \
+php-s pht phtml pif pl plg pm pod prf prg ps1 ps2 ps1xml ps2xml psc1 psc2 \
+psd1 psm1 pssc pst py py3 pyc pyd pyi pyo pyw pywz pyz rb reg rgs scf scr \
+sct search-ms settingcontent-ms sh shb shs slk sys t tmp u3p url vb vbe vbp \
+vbs vbscript vdx vsmacros vsd vsdm vsdx vss vssm vssx vst vstm vstx vsw vsx \
+vtx website ws wsc wsf wsh xbap xll xnk xs");
+#endif // !Q_OS_MAC && !Q_OS_UNIX
+		const auto list = joined.split(' ');
+		return base::flat_set<QString>(list.begin(), list.end());
+	}();
+
+	return ranges::binary_search(
+		kExtensions,
+		FileExtension(filepath).toLower());
+}
+
+bool IsIpRevealingName(const QString &filepath) {
+	static const auto kExtensions = [] {
+		const auto joined = u"htm html svg"_q;
+		const auto list = joined.split(' ');
+		return base::flat_set<QString>(list.begin(), list.end());
+	}();
+	static const auto kMimeTypes = [] {
+		const auto joined = u"text/html image/svg+xml"_q;
+		const auto list = joined.split(' ');
+		return base::flat_set<QString>(list.begin(), list.end());
+	}();
+
+	return ranges::binary_search(
+		kExtensions,
+		FileExtension(filepath).toLower()
+	) || ranges::binary_search(
+		kMimeTypes,
+		QMimeDatabase().mimeTypeForFile(QFileInfo(filepath)).name()
+	);
+}
+
+base::binary_guard ReadImageAsync(
+		not_null<Data::DocumentMedia*> media,
+		FnMut<QImage(QImage)> postprocess,
+		FnMut<void(QImage&&)> done) {
+	auto result = base::binary_guard();
+	crl::async([
+		bytes = media->bytes(),
+		path = media->owner()->filepath(),
+		postprocess = std::move(postprocess),
+		guard = result.make_guard(),
+		callback = std::move(done)
+	]() mutable {
+		auto format = QByteArray();
+		if (bytes.isEmpty()) {
+			QFile f(path);
+			if (f.size() <= App::kImageSizeLimit
+				&& f.open(QIODevice::ReadOnly)) {
+				bytes = f.readAll();
+			}
+		}
+		auto image = bytes.isEmpty()
+			? QImage()
+			: App::readImage(bytes, &format, false, nullptr);
+		if (postprocess) {
+			image = postprocess(std::move(image));
+		}
+		crl::on_main(std::move(guard), [
+			image = std::move(image),
+			callback = std::move(callback)
+		]() mutable {
+			callback(std::move(image));
+		});
+	});
+	return result;
+}
+
+void ResolveDocument(
+		// not_null<Window::Controller*> controller,
+		not_null<DocumentData*> document,
+		HistoryItem *item) {
+	if (!document->date) {
+		return;
+	}
+
+	const auto media = document->createMediaView();
+	const auto openImageInApp = [&] {
+		if (document->size >= App::kImageSizeLimit) {
+			return false;
+		}
+		const auto &location = document->location(true);
+		if (!location.isEmpty() && location.accessEnable()) {
+			const auto guard = gsl::finally([&] {
+				location.accessDisable();
+			});
+			const auto path = location.name();
+			if (Core::MimeTypeForFile(path).name().startsWith("image/")
+				&& QImageReader(path).canRead()) {
+				Core::App().showDocument(document, item);
+				return true;
+			}
+		} else if (document->mimeString().startsWith("image/")
+			&& !media->bytes().isEmpty()) {
+			auto bytes = media->bytes();
+			auto buffer = QBuffer(&bytes);
+			if (QImageReader(&buffer).canRead()) {
+				Core::App().showDocument(document, item);
+				return true;
+			}
+		}
+		return false;
+	};
+	const auto &location = document->location(true);
+	if (document->isTheme() && media->loaded(true)) {
+		Core::App().showDocument(document, item);
+		location.accessDisable();
+	} else if (media->canBePlayed()) {
+		if (document->isAudioFile()
+			|| document->isVoiceMessage()
+			|| document->isVideoMessage()) {
+			const auto msgId = item ? item->fullId() : FullMsgId();
+			::Media::Player::instance()->playPause({ document, msgId });
+		} else if (item
+			&& document->isAnimation()
+			&& HistoryView::Gif::CanPlayInline(document)) {
+			document->owner().requestAnimationPlayInline(item);
+		} else {
+			Core::App().showDocument(document, item);
+		}
+	} else {
+		document->saveFromDataSilent();
+		if (!openImageInApp()) {
+			if (!document->filepath(true).isEmpty()) {
+				LaunchWithWarning(location.name(), item);
+			} else if (document->status == FileReady
+				|| document->status == FileDownloadFailed) {
+				DocumentSaveClickHandler::Save(
+					item ? item->fullId() : Data::FileOrigin(),
+					document);
+			}
+		}
+	}
+}
+
+} // namespace Data
diff --git a/Telegram/SourceFiles/data/data_document_resolver.h b/Telegram/SourceFiles/data/data_document_resolver.h
new file mode 100644
index 000000000..d52c50eb0
--- /dev/null
+++ b/Telegram/SourceFiles/data/data_document_resolver.h
@@ -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
+
+#include "base/binary_guard.h"
+
+class DocumentData;
+class HistoryItem;
+
+namespace Window {
+class Controller;
+} // namespace Window
+
+namespace Data {
+
+class DocumentMedia;
+
+[[nodiscard]] QString FileExtension(const QString &filepath);
+// [[nodiscard]] bool IsValidMediaFile(const QString &filepath);
+[[nodiscard]] bool IsExecutableName(const QString &filepath);
+[[nodiscard]] bool IsIpRevealingName(const QString &filepath);
+base::binary_guard ReadImageAsync(
+	not_null<Data::DocumentMedia*> media,
+	FnMut<QImage(QImage)> postprocess,
+	FnMut<void(QImage&&)> done);
+
+void ResolveDocument(
+	// not_null<Window::Controller*> controller,
+	not_null<DocumentData*> document,
+	HistoryItem *item);
+
+} // namespace Data
diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp
index ede2ea5ae..c48f410ca 100644
--- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp
+++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp
@@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "data/data_session.h"
 #include "data/data_document.h"
 #include "data/data_document_media.h"
+#include "data/data_document_resolver.h"
 #include "data/data_media_types.h"
 #include "data/data_file_origin.h"
 #include "styles/style_chat.h"
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index 4d094ba41..1d7fc40e9 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "data/data_photo.h"
 #include "data/data_document.h"
 #include "data/data_document_media.h"
+#include "data/data_document_resolver.h"
 #include "data/data_web_page.h"
 #include "data/data_game.h"
 #include "data/data_peer_values.h"
diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp
index bae062b05..b0d43e532 100644
--- a/Telegram/SourceFiles/overview/overview_layout.cpp
+++ b/Telegram/SourceFiles/overview/overview_layout.cpp
@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 
 #include "overview/overview_layout_delegate.h"
 #include "data/data_document.h"
+#include "data/data_document_resolver.h"
 #include "data/data_session.h"
 #include "data/data_web_page.h"
 #include "data/data_media_types.h"