From e266dc153b41d2f4fa5042ec8232e23f91feca36 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 21 Jan 2020 23:31:34 +0300 Subject: [PATCH] Implemented ability to add more than 1 file to albums via SendFilesBox. --- Telegram/Resources/langs/lang.strings | 1 + .../SourceFiles/boxes/edit_caption_box.cpp | 20 +---- Telegram/SourceFiles/boxes/send_files_box.cpp | 30 ++------ .../storage/storage_media_prepare.cpp | 75 +++++++++++++------ .../storage/storage_media_prepare.h | 8 +- 5 files changed, 68 insertions(+), 66 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index ca1c39c556..f37d4c4e02 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1457,6 +1457,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_send_album" = "Send as an album"; "lng_send_photo" = "Send as a photo"; "lng_send_file" = "Send as a file"; +"lng_send_media_invalid_files" = "Sorry, no valid files found."; "lng_forward_choose" = "Choose recipient..."; "lng_forward_cant" = "Sorry, no way to forward here :("; diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index 7a205edbaf..dd20abb012 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -488,26 +488,14 @@ void EditCaptionBox::updateEditMediaButton() { void EditCaptionBox::createEditMediaButton() { const auto callback = [=](FileDialog::OpenResult &&result) { - - auto isValidFile = [](QString mimeType) { - if (Core::IsMimeSticker(mimeType)) { - Ui::show( - Box(tr::lng_edit_media_invalid_file(tr::now)), - Ui::LayerOption::KeepOther); - return false; - } - return true; + auto showBoxErrorCallback = [](tr::phrase<> t) { + Ui::show(Box(t(tr::now)), Ui::LayerOption::KeepOther); }; - auto list = Storage::PreparedList::PreparedFileFromFileDialog( + auto list = Storage::PreparedList::PreparedFileFromFilesDialog( std::move(result), _isAlbum, - [] { - Ui::show( - Box(tr::lng_edit_media_album_error(tr::now)), - Ui::LayerOption::KeepOther); - }, - std::move(isValidFile), + std::move(showBoxErrorCallback), st::sendMediaPreviewSize); if (list) { diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 9ccd4abd70..cb9075432d 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -129,27 +129,14 @@ void FileDialogCallback( FileDialog::OpenResult &&result, bool isAlbum, Fn callback) { - auto isValidFile = [](QString mimeType) { - if (!Core::IsMimeSticker(mimeType)) { - return true; - } - Ui::show( - Box(tr::lng_edit_media_invalid_file(tr::now)), - Ui::LayerOption::KeepOther); - return false; + auto showBoxErrorCallback = [](tr::phrase<> text) { + Ui::show(Box(text(tr::now)), Ui::LayerOption::KeepOther); }; - auto errorCallback = [] { - Ui::show( - Box(tr::lng_edit_media_album_error(tr::now)), - Ui::LayerOption::KeepOther); - }; - - auto list = Storage::PreparedList::PreparedFileFromFileDialog( + auto list = Storage::PreparedList::PreparedFileFromFilesDialog( std::move(result), isAlbum, - std::move(errorCallback), - std::move(isValidFile), + std::move(showBoxErrorCallback), st::sendMediaPreviewSize); if (!list) { @@ -1900,7 +1887,7 @@ void SendFilesBox::openDialogToAddFileToAlbum() { }); }; - FileDialog::GetOpenPath( + FileDialog::GetOpenPaths( this, tr::lng_choose_file(tr::now), FileDialog::AlbumFilesFilter(), @@ -2197,9 +2184,8 @@ bool SendFilesBox::addFiles(not_null data) { bool SendFilesBox::addFiles(Storage::PreparedList list) { const auto sumFiles = _list.files.size() + list.files.size(); - if (sumFiles > Storage::MaxAlbumItems()) { - return false; - } else if (list.error != Storage::PreparedList::Error::None) { + const auto cutToAlbumSize = (sumFiles > Storage::MaxAlbumItems()); + if (list.error != Storage::PreparedList::Error::None) { return false; } else if (!IsSingleItem(list) && !list.albumIsPossible) { return false; @@ -2218,7 +2204,7 @@ bool SendFilesBox::addFiles(Storage::PreparedList list) { && _sendWay->value() == SendFilesWay::Photos) { _sendWay->setValue(SendFilesWay::Album); } - _list.mergeToEnd(std::move(list)); + _list.mergeToEnd(std::move(list), cutToAlbumSize); _compressConfirm = _compressConfirmInitial; refreshAllAfterAlbumChanges(); diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.cpp b/Telegram/SourceFiles/storage/storage_media_prepare.cpp index 65c53a0e80..1a28101cc1 100644 --- a/Telegram/SourceFiles/storage/storage_media_prepare.cpp +++ b/Telegram/SourceFiles/storage/storage_media_prepare.cpp @@ -276,11 +276,10 @@ PreparedList PrepareMediaFromImage( return result; } -std::optional PreparedList::PreparedFileFromFileDialog( +std::optional PreparedList::PreparedFileFromFilesDialog( FileDialog::OpenResult &&result, bool isAlbum, - Fn errorCallback, - Fn isValidFileCallback, + Fn)> errorCallback, int previewWidth) { if (result.paths.isEmpty() && result.remoteContent.isEmpty()) { return std::nullopt; @@ -293,7 +292,8 @@ std::optional PreparedList::PreparedFileFromFileDialog( std::move(result.remoteContent), previewWidth); - if (!isValidFileCallback(list.files.front().mime)) { + if (Core::IsMimeSticker(list.files.front().mime)) { + errorCallback(tr::lng_edit_media_invalid_file); return std::nullopt; } @@ -304,46 +304,68 @@ std::optional PreparedList::PreparedFileFromFileDialog( "video/mp4", }; const auto file = &list.files.front(); - if (ranges::find(albumMimes, file->mime) == end(albumMimes) + if (!ranges::contains(albumMimes, file->mime) || file->type == Storage::PreparedFile::AlbumType::None) { - errorCallback(); + errorCallback(tr::lng_edit_media_album_error); return std::nullopt; } } Expects(list.files.size() == 1); return std::move(list); } else if (!result.paths.isEmpty()) { - auto list = Storage::PrepareMediaList( - QStringList(result.paths.front()), - previewWidth); - - // Don't rewrite _preparedList if a new list is not valid for album. - if (isAlbum) { + const auto isSingleFile = (result.paths.size() == 1); + auto temp = Storage::PrepareMediaList(result.paths, previewWidth); + if (temp.error != PreparedList::Error::None) { + errorCallback(tr::lng_send_media_invalid_files); + return std::nullopt; + } + auto filteredFiles = ranges::view::all( + temp.files + ) | ranges::view::filter([&](const auto &file) { + if (!isAlbum) { + return true; + } + const auto info = QFileInfo(file.path); + if (Core::IsMimeSticker(Core::MimeTypeForFile(info).name())) { + if (isSingleFile) { + errorCallback(tr::lng_edit_media_invalid_file); + } + return false; + } using Info = FileMediaInformation; - const auto media = &list.files.front().information->media; - const auto valid = media->match([&](const Info::Image &data) { + const auto media = &file.information->media; + const auto valid = media->match([](const Info::Image &data) { return Storage::ValidateThumbDimensions( data.data.width(), data.data.height()) && !data.animated; - }, [&](Info::Video &data) { + }, [](Info::Video &data) { data.isGifv = false; return true; }, [](auto &&other) { return false; }); - if (!valid) { - errorCallback(); - return std::nullopt; + if (!valid && isSingleFile) { + errorCallback(tr::lng_edit_media_album_error); + } + return valid; + }) | ranges::view::transform([](auto &file) { + return std::move(file); + }) | ranges::to_vector; + + if (!filteredFiles.size()) { + if (!isSingleFile) { + errorCallback(tr::lng_send_media_invalid_files); } - } - const auto info = QFileInfo(result.paths.front()); - if (!isValidFileCallback(Core::MimeTypeForFile(info).name())) { return std::nullopt; } - Expects(list.files.size() == 1); + auto list = PreparedList(temp.error, temp.errorData); + list.albumIsPossible = isAlbum; + list.allFilesForCompress = temp.allFilesForCompress; + list.files = std::move(filteredFiles); + return std::move(list); } return std::nullopt; @@ -365,7 +387,7 @@ PreparedList PreparedList::Reordered( return result; } -void PreparedList::mergeToEnd(PreparedList &&other) { +void PreparedList::mergeToEnd(PreparedList &&other, bool cutToAlbumSize) { if (error != Error::None) { return; } @@ -375,9 +397,14 @@ void PreparedList::mergeToEnd(PreparedList &&other) { return; } allFilesForCompress = allFilesForCompress && other.allFilesForCompress; - files.reserve(files.size() + other.files.size()); + files.reserve(std::min( + size_t(cutToAlbumSize ? kMaxAlbumCount : INT_MAX), + files.size() + other.files.size())); for (auto &file : other.files) { files.push_back(std::move(file)); + if (cutToAlbumSize && files.size() == kMaxAlbumCount) { + break; + } } if (files.size() > 1 && files.size() <= kMaxAlbumCount) { const auto badIt = ranges::find( diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.h b/Telegram/SourceFiles/storage/storage_media_prepare.h index f75027d875..5ed80d445b 100644 --- a/Telegram/SourceFiles/storage/storage_media_prepare.h +++ b/Telegram/SourceFiles/storage/storage_media_prepare.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "core/file_utilities.h" +#include "lang/lang_keys.h" struct FileMediaInformation; @@ -61,13 +62,12 @@ struct PreparedList { static PreparedList Reordered( PreparedList &&list, std::vector order); - static std::optional PreparedFileFromFileDialog( + static std::optional PreparedFileFromFilesDialog( FileDialog::OpenResult &&result, bool isAlbum, - Fn errorCallback, - Fn isValidFileCallback, + Fn)> errorCallback, int previewWidth); - void mergeToEnd(PreparedList &&other); + void mergeToEnd(PreparedList &&other, bool cutToAlbumSize = false); bool canAddCaption(bool isAlbum, bool compressImages) const;