From 5f8c2f90ff8524fa7955156a74dd032a579065d2 Mon Sep 17 00:00:00 2001
From: 23rd <23rd@vivaldi.net>
Date: Mon, 6 Jan 2020 00:04:47 +0300
Subject: [PATCH] Added button to add new files in SendFilesBox to album only.

---
 .../SourceFiles/boxes/edit_caption_box.cpp    |   2 +-
 Telegram/SourceFiles/boxes/send_files_box.cpp | 133 ++++++++++++------
 Telegram/SourceFiles/boxes/send_files_box.h   |   5 +
 .../storage/storage_media_prepare.cpp         |   2 +-
 .../storage/storage_media_prepare.h           |   2 +-
 5 files changed, 100 insertions(+), 44 deletions(-)

diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp
index 7c76d3d05..fb024a685 100644
--- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp
+++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp
@@ -499,7 +499,7 @@ void EditCaptionBox::createEditMediaButton() {
 			return true;
 		};
 
-		auto list = Storage::PreparedList::EditedPreparedFile(
+		auto list = Storage::PreparedList::PreparedFileFromFileDialog(
 			std::move(result),
 			_isAlbum,
 			[] {
diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp
index eb3334441..094d9a087 100644
--- a/Telegram/SourceFiles/boxes/send_files_box.cpp
+++ b/Telegram/SourceFiles/boxes/send_files_box.cpp
@@ -126,6 +126,40 @@ void PaintAlbumThumbButtons(
 
 }
 
+void FileDialogCallback(
+	FileDialog::OpenResult &&result,
+	bool isAlbum,
+	Fn<void(Storage::PreparedList)> callback) {
+	auto isValidFile = [](QString mimeType) {
+		if (mimeType != qstr("image/webp")) {
+			return true;
+		}
+		Ui::show(
+			Box<InformBox>(tr::lng_edit_media_invalid_file(tr::now)),
+			Ui::LayerOption::KeepOther);
+		return false;
+	};
+
+	auto errorCallback = [] {
+		Ui::show(
+			Box<InformBox>(tr::lng_edit_media_album_error(tr::now)),
+			Ui::LayerOption::KeepOther);
+	};
+
+	auto list = Storage::PreparedList::PreparedFileFromFileDialog(
+		std::move(result),
+		isAlbum,
+		std::move(errorCallback),
+		std::move(isValidFile),
+		st::sendMediaPreviewSize);
+
+	if (!list) {
+		return;
+	}
+
+	callback(std::move(*list));
+}
+
 class SingleMediaPreview : public Ui::RpWidget {
 public:
 	static SingleMediaPreview *Create(
@@ -1631,9 +1665,7 @@ void SendFilesBox::addThumbButtonHandlers() {
 		}
 
 		_compressConfirm = _compressConfirmInitial;
-		refreshAlbumMediaCount();
-		preparePreview();
-		captionResized();
+		refreshAllAfterAlbumChanges();
 
 	}, _albumPreview->lifetime());
 
@@ -1641,44 +1673,20 @@ void SendFilesBox::addThumbButtonHandlers() {
 	) | rpl::start_with_next([=](auto index) {
 
 		const auto callback = [=](FileDialog::OpenResult &&result) {
-			auto isValidFile = [](QString mimeType) {
-				if (mimeType != qstr("image/webp")) {
-					return true;
-				}
-				Ui::show(
-					Box<InformBox>(tr::lng_edit_media_invalid_file(tr::now)),
-					Ui::LayerOption::KeepOther);
-				return false;
-			};
-
-			auto errorCallback = [] {
-				Ui::show(
-					Box<InformBox>(tr::lng_edit_media_album_error(tr::now)),
-					Ui::LayerOption::KeepOther);
-			};
-
-			auto list = Storage::PreparedList::EditedPreparedFile(
+			FileDialogCallback(
 				std::move(result),
 				true,
-				std::move(errorCallback),
-				std::move(isValidFile),
-				st::sendMediaPreviewSize);
+				[=] (auto list) {
+					_list.files[index] = std::move(list.files.front());
+					applyAlbumOrder();
 
-			if (!list) {
-				return;
-			}
+					if (_preview) {
+						_preview->deleteLater();
+					}
+					_albumPreview = nullptr;
 
-			_list.files[index] = std::move((*list).files.front());
-			applyAlbumOrder();
-
-			if (_preview) {
-				_preview->deleteLater();
-			}
-			_albumPreview = nullptr;
-
-			refreshAlbumMediaCount();
-			preparePreview();
-			captionResized();
+					refreshAllAfterAlbumChanges();
+				});
 		};
 
 		FileDialog::GetOpenPath(
@@ -1738,6 +1746,49 @@ void SendFilesBox::prepare() {
 			_cancelledCallback();
 		}
 	}, lifetime());
+
+	const auto title = tr::lng_stickers_featured_add(tr::now) + qsl("...");
+	_addFileToAlbum = addLeftButton(
+		rpl::single(title),
+		App::LambdaDelayed(st::historyAttach.ripple.hideDuration, this, [=] {
+			openDialogToAddFileToAlbum();
+		}));
+
+	updateLeftButtonVisibility();
+}
+
+void SendFilesBox::updateLeftButtonVisibility() {
+	const auto isAlbum = _list.albumIsPossible
+		&& (_list.files.size() < Storage::MaxAlbumItems());
+	if (isAlbum || (IsSingleItem(_list) && IsFirstAlbumItem(_list))) {
+		_addFileToAlbum->show();
+	} else {
+		_addFileToAlbum->hide();
+	}
+}
+
+void SendFilesBox::refreshAllAfterAlbumChanges() {
+	refreshAlbumMediaCount();
+	preparePreview();
+	captionResized();
+	updateLeftButtonVisibility();
+}
+
+void SendFilesBox::openDialogToAddFileToAlbum() {
+	const auto callback = [=](FileDialog::OpenResult &&result) {
+		FileDialogCallback(
+			std::move(result),
+			true,
+			[=] (auto list) {
+				addFiles(std::move(list));
+			});
+	};
+
+	FileDialog::GetOpenPath(
+		this,
+		tr::lng_choose_file(tr::now),
+		FileDialog::AlbumFilesFilter(),
+		crl::guard(this, callback));
 }
 
 void SendFilesBox::initSendWay() {
@@ -2054,9 +2105,7 @@ bool SendFilesBox::addFiles(Storage::PreparedList list) {
 	_list.mergeToEnd(std::move(list));
 
 	_compressConfirm = _compressConfirmInitial;
-	refreshAlbumMediaCount();
-	preparePreview();
-	captionResized();
+	refreshAllAfterAlbumChanges();
 	return true;
 }
 
@@ -2094,7 +2143,9 @@ void SendFilesBox::updateBoxSize() {
 }
 
 void SendFilesBox::keyPressEvent(QKeyEvent *e) {
-	if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
+	if (e->matches(QKeySequence::Open) && !_addFileToAlbum->isHidden()) {
+		openDialogToAddFileToAlbum();
+	} else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
 		const auto modifiers = e->modifiers();
 		const auto ctrl = modifiers.testFlag(Qt::ControlModifier)
 			|| modifiers.testFlag(Qt::MetaModifier);
diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h
index 16e5dd95f..f90c38218 100644
--- a/Telegram/SourceFiles/boxes/send_files_box.h
+++ b/Telegram/SourceFiles/boxes/send_files_box.h
@@ -126,6 +126,10 @@ private:
 	bool addFiles(not_null<const QMimeData*> data);
 	bool addFiles(Storage::PreparedList list);
 
+	void openDialogToAddFileToAlbum();
+	void updateLeftButtonVisibility();
+	void refreshAllAfterAlbumChanges();
+
 	const not_null<Window::SessionController*> _controller;
 	const Api::SendType _sendType = Api::SendType();
 
@@ -166,5 +170,6 @@ private:
 	int _albumPhotosCount = 0;
 
 	QPointer<Ui::RoundButton> _send;
+	QPointer<Ui::RoundButton> _addFileToAlbum;
 
 };
diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.cpp b/Telegram/SourceFiles/storage/storage_media_prepare.cpp
index 450c9102e..693a77e84 100644
--- a/Telegram/SourceFiles/storage/storage_media_prepare.cpp
+++ b/Telegram/SourceFiles/storage/storage_media_prepare.cpp
@@ -278,7 +278,7 @@ PreparedList PrepareMediaFromImage(
 	return result;
 }
 
-std::optional<PreparedList> PreparedList::EditedPreparedFile(
+std::optional<PreparedList> PreparedList::PreparedFileFromFileDialog(
 		FileDialog::OpenResult &&result,
 		bool isAlbum,
 		Fn<void()> errorCallback,
diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.h b/Telegram/SourceFiles/storage/storage_media_prepare.h
index 3d02fbc6a..f75027d87 100644
--- a/Telegram/SourceFiles/storage/storage_media_prepare.h
+++ b/Telegram/SourceFiles/storage/storage_media_prepare.h
@@ -61,7 +61,7 @@ struct PreparedList {
 	static PreparedList Reordered(
 		PreparedList &&list,
 		std::vector<int> order);
-	static std::optional<PreparedList> EditedPreparedFile(
+	static std::optional<PreparedList> PreparedFileFromFileDialog(
 		FileDialog::OpenResult &&result,
 		bool isAlbum,
 		Fn<void()> errorCallback,