From 19139a9a5f962e684a4b8e224b53cb7138d90659 Mon Sep 17 00:00:00 2001
From: 23rd <23rd@vivaldi.net>
Date: Mon, 12 Jul 2021 13:50:02 +0300
Subject: [PATCH] Added ability to generate single file preview from history
 item.

---
 Telegram/CMakeLists.txt                       |   2 +
 .../attach_item_single_file_preview.cpp       | 101 ++++++++++++++++++
 .../attach/attach_item_single_file_preview.h  |  39 +++++++
 3 files changed, 142 insertions(+)
 create mode 100644 Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.cpp
 create mode 100644 Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.h

diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt
index e31886e43..e49b62047 100644
--- a/Telegram/CMakeLists.txt
+++ b/Telegram/CMakeLists.txt
@@ -1069,6 +1069,8 @@ PRIVATE
     support/support_helper.h
     support/support_templates.cpp
     support/support_templates.h
+    ui/chat/attach/attach_item_single_file_preview.cpp
+    ui/chat/attach/attach_item_single_file_preview.h
     ui/effects/fireworks_animation.cpp
     ui/effects/fireworks_animation.h
     ui/effects/round_checkbox.cpp
diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.cpp
new file mode 100644
index 000000000..608320e0b
--- /dev/null
+++ b/Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.cpp
@@ -0,0 +1,101 @@
+/*
+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 "ui/chat/attach/attach_item_single_file_preview.h"
+
+#include "data/data_document.h"
+#include "data/data_document_media.h"
+#include "data/data_file_origin.h"
+#include "history/history_item.h"
+#include "history/view/media/history_view_document.h"
+#include "lang/lang_keys.h"
+#include "main/main_session.h"
+#include "ui/chat/attach/attach_prepare.h"
+#include "ui/text/format_song_name.h"
+#include "ui/text/format_values.h"
+#include "styles/style_chat.h"
+
+namespace Ui {
+
+ItemSingleFilePreview::ItemSingleFilePreview(
+	QWidget *parent,
+	not_null<HistoryItem*> item)
+: AbstractSingleFilePreview(parent) {
+	const auto media = item->media();
+	Assert(media != nullptr);
+	const auto document = media->document();
+	Assert(document != nullptr);
+
+	_documentMedia = document->createMediaView();
+	_documentMedia->thumbnailWanted(item->fullId());
+
+	rpl::single(
+		rpl::empty_value()
+	) | rpl::then(
+		document->session().downloaderTaskFinished()
+	) | rpl::start_with_next([=] {
+		if (_documentMedia->thumbnail()) {
+			_lifetimeDownload.destroy();
+		}
+		preparePreview(document);
+	}, _lifetimeDownload);
+}
+
+void ItemSingleFilePreview::preparePreview(not_null<DocumentData*> document) {
+	AbstractSingleFilePreview::Data data;
+
+	const auto preview = _documentMedia->thumbnail()
+		? _documentMedia->thumbnail()->original()
+		: QImage();
+
+	prepareThumbFor(data, preview);
+	data.fileIsImage = document->isImage();
+	data.fileIsAudio = document->isAudioFile() || document->isVoiceMessage();
+
+	if (data.fileIsImage) {
+		data.name = document->filename();
+		// data.statusText = FormatImageSizeText(preview.size()
+		// 	/ preview.devicePixelRatio());
+	} else if (data.fileIsAudio) {
+		auto filename = document->filename();
+
+		auto songTitle = QString();
+		auto songPerformer = QString();
+		if (const auto song = document->song()) {
+			songTitle = song->title;
+			songPerformer = song->performer;
+
+			if (document->isSongWithCover()) {
+				const auto size = QSize(
+					st::attachPreviewLayout.thumbSize,
+					st::attachPreviewLayout.thumbSize);
+				auto thumb = QPixmap(size);
+				thumb.fill(Qt::transparent);
+				Painter p(&thumb);
+
+				HistoryView::DrawThumbnailAsSongCover(
+					p,
+					_documentMedia,
+					QRect(QPoint(), size));
+				data.fileThumb = std::move(thumb);
+			}
+		} else if (document->isVoiceMessage()) {
+			songTitle = tr::lng_media_audio(tr::now);
+		}
+
+		data.name = Text::FormatSongName(filename, songTitle, songPerformer)
+			.string();
+		data.statusText = FormatSizeText(document->size);
+	} else {
+		data.name = document->filename();
+	}
+	data.statusText = FormatSizeText(document->size);
+
+	setData(data);
+}
+
+} // namespace Ui
diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.h b/Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.h
new file mode 100644
index 000000000..db6e90d79
--- /dev/null
+++ b/Telegram/SourceFiles/ui/chat/attach/attach_item_single_file_preview.h
@@ -0,0 +1,39 @@
+/*
+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 "ui/chat/attach/attach_abstract_single_file_preview.h"
+
+class HistoryItem;
+class DocumentData;
+
+namespace Data {
+class DocumentMedia;
+} // namespace Data
+
+namespace Ui {
+
+struct PreparedFile;
+class IconButton;
+
+class ItemSingleFilePreview final : public AbstractSingleFilePreview {
+public:
+	ItemSingleFilePreview(
+		QWidget *parent,
+		not_null<HistoryItem*> item);
+
+private:
+	void preparePreview(not_null<DocumentData*> document);
+
+	std::shared_ptr<::Data::DocumentMedia> _documentMedia;
+
+	rpl::lifetime _lifetimeDownload;
+
+};
+
+} // namespace Ui