Implemented ability to add more than 1 file to albums via SendFilesBox.

This commit is contained in:
23rd 2020-01-21 23:31:34 +03:00 committed by John Preston
parent a482b744d2
commit e266dc153b
5 changed files with 68 additions and 66 deletions

View File

@ -1457,6 +1457,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_send_album" = "Send as an album"; "lng_send_album" = "Send as an album";
"lng_send_photo" = "Send as a photo"; "lng_send_photo" = "Send as a photo";
"lng_send_file" = "Send as a file"; "lng_send_file" = "Send as a file";
"lng_send_media_invalid_files" = "Sorry, no valid files found.";
"lng_forward_choose" = "Choose recipient..."; "lng_forward_choose" = "Choose recipient...";
"lng_forward_cant" = "Sorry, no way to forward here :("; "lng_forward_cant" = "Sorry, no way to forward here :(";

View File

@ -488,26 +488,14 @@ void EditCaptionBox::updateEditMediaButton() {
void EditCaptionBox::createEditMediaButton() { void EditCaptionBox::createEditMediaButton() {
const auto callback = [=](FileDialog::OpenResult &&result) { const auto callback = [=](FileDialog::OpenResult &&result) {
auto showBoxErrorCallback = [](tr::phrase<> t) {
auto isValidFile = [](QString mimeType) { Ui::show(Box<InformBox>(t(tr::now)), Ui::LayerOption::KeepOther);
if (Core::IsMimeSticker(mimeType)) {
Ui::show(
Box<InformBox>(tr::lng_edit_media_invalid_file(tr::now)),
Ui::LayerOption::KeepOther);
return false;
}
return true;
}; };
auto list = Storage::PreparedList::PreparedFileFromFileDialog( auto list = Storage::PreparedList::PreparedFileFromFilesDialog(
std::move(result), std::move(result),
_isAlbum, _isAlbum,
[] { std::move(showBoxErrorCallback),
Ui::show(
Box<InformBox>(tr::lng_edit_media_album_error(tr::now)),
Ui::LayerOption::KeepOther);
},
std::move(isValidFile),
st::sendMediaPreviewSize); st::sendMediaPreviewSize);
if (list) { if (list) {

View File

@ -129,27 +129,14 @@ void FileDialogCallback(
FileDialog::OpenResult &&result, FileDialog::OpenResult &&result,
bool isAlbum, bool isAlbum,
Fn<void(Storage::PreparedList)> callback) { Fn<void(Storage::PreparedList)> callback) {
auto isValidFile = [](QString mimeType) { auto showBoxErrorCallback = [](tr::phrase<> text) {
if (!Core::IsMimeSticker(mimeType)) { Ui::show(Box<InformBox>(text(tr::now)), Ui::LayerOption::KeepOther);
return true;
}
Ui::show(
Box<InformBox>(tr::lng_edit_media_invalid_file(tr::now)),
Ui::LayerOption::KeepOther);
return false;
}; };
auto errorCallback = [] { auto list = Storage::PreparedList::PreparedFileFromFilesDialog(
Ui::show(
Box<InformBox>(tr::lng_edit_media_album_error(tr::now)),
Ui::LayerOption::KeepOther);
};
auto list = Storage::PreparedList::PreparedFileFromFileDialog(
std::move(result), std::move(result),
isAlbum, isAlbum,
std::move(errorCallback), std::move(showBoxErrorCallback),
std::move(isValidFile),
st::sendMediaPreviewSize); st::sendMediaPreviewSize);
if (!list) { if (!list) {
@ -1900,7 +1887,7 @@ void SendFilesBox::openDialogToAddFileToAlbum() {
}); });
}; };
FileDialog::GetOpenPath( FileDialog::GetOpenPaths(
this, this,
tr::lng_choose_file(tr::now), tr::lng_choose_file(tr::now),
FileDialog::AlbumFilesFilter(), FileDialog::AlbumFilesFilter(),
@ -2197,9 +2184,8 @@ bool SendFilesBox::addFiles(not_null<const QMimeData*> data) {
bool SendFilesBox::addFiles(Storage::PreparedList list) { bool SendFilesBox::addFiles(Storage::PreparedList list) {
const auto sumFiles = _list.files.size() + list.files.size(); const auto sumFiles = _list.files.size() + list.files.size();
if (sumFiles > Storage::MaxAlbumItems()) { const auto cutToAlbumSize = (sumFiles > Storage::MaxAlbumItems());
return false; if (list.error != Storage::PreparedList::Error::None) {
} else if (list.error != Storage::PreparedList::Error::None) {
return false; return false;
} else if (!IsSingleItem(list) && !list.albumIsPossible) { } else if (!IsSingleItem(list) && !list.albumIsPossible) {
return false; return false;
@ -2218,7 +2204,7 @@ bool SendFilesBox::addFiles(Storage::PreparedList list) {
&& _sendWay->value() == SendFilesWay::Photos) { && _sendWay->value() == SendFilesWay::Photos) {
_sendWay->setValue(SendFilesWay::Album); _sendWay->setValue(SendFilesWay::Album);
} }
_list.mergeToEnd(std::move(list)); _list.mergeToEnd(std::move(list), cutToAlbumSize);
_compressConfirm = _compressConfirmInitial; _compressConfirm = _compressConfirmInitial;
refreshAllAfterAlbumChanges(); refreshAllAfterAlbumChanges();

View File

@ -276,11 +276,10 @@ PreparedList PrepareMediaFromImage(
return result; return result;
} }
std::optional<PreparedList> PreparedList::PreparedFileFromFileDialog( std::optional<PreparedList> PreparedList::PreparedFileFromFilesDialog(
FileDialog::OpenResult &&result, FileDialog::OpenResult &&result,
bool isAlbum, bool isAlbum,
Fn<void()> errorCallback, Fn<void(tr::phrase<>)> errorCallback,
Fn<bool(QString)> isValidFileCallback,
int previewWidth) { int previewWidth) {
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) { if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
return std::nullopt; return std::nullopt;
@ -293,7 +292,8 @@ std::optional<PreparedList> PreparedList::PreparedFileFromFileDialog(
std::move(result.remoteContent), std::move(result.remoteContent),
previewWidth); previewWidth);
if (!isValidFileCallback(list.files.front().mime)) { if (Core::IsMimeSticker(list.files.front().mime)) {
errorCallback(tr::lng_edit_media_invalid_file);
return std::nullopt; return std::nullopt;
} }
@ -304,46 +304,68 @@ std::optional<PreparedList> PreparedList::PreparedFileFromFileDialog(
"video/mp4", "video/mp4",
}; };
const auto file = &list.files.front(); 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) { || file->type == Storage::PreparedFile::AlbumType::None) {
errorCallback(); errorCallback(tr::lng_edit_media_album_error);
return std::nullopt; return std::nullopt;
} }
} }
Expects(list.files.size() == 1); Expects(list.files.size() == 1);
return std::move(list); return std::move(list);
} else if (!result.paths.isEmpty()) { } else if (!result.paths.isEmpty()) {
auto list = Storage::PrepareMediaList( const auto isSingleFile = (result.paths.size() == 1);
QStringList(result.paths.front()), auto temp = Storage::PrepareMediaList(result.paths, previewWidth);
previewWidth); if (temp.error != PreparedList::Error::None) {
errorCallback(tr::lng_send_media_invalid_files);
// Don't rewrite _preparedList if a new list is not valid for album. return std::nullopt;
if (isAlbum) { }
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; using Info = FileMediaInformation;
const auto media = &list.files.front().information->media; const auto media = &file.information->media;
const auto valid = media->match([&](const Info::Image &data) { const auto valid = media->match([](const Info::Image &data) {
return Storage::ValidateThumbDimensions( return Storage::ValidateThumbDimensions(
data.data.width(), data.data.width(),
data.data.height()) data.data.height())
&& !data.animated; && !data.animated;
}, [&](Info::Video &data) { }, [](Info::Video &data) {
data.isGifv = false; data.isGifv = false;
return true; return true;
}, [](auto &&other) { }, [](auto &&other) {
return false; return false;
}); });
if (!valid) { if (!valid && isSingleFile) {
errorCallback(); errorCallback(tr::lng_edit_media_album_error);
return std::nullopt; }
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; 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::move(list);
} }
return std::nullopt; return std::nullopt;
@ -365,7 +387,7 @@ PreparedList PreparedList::Reordered(
return result; return result;
} }
void PreparedList::mergeToEnd(PreparedList &&other) { void PreparedList::mergeToEnd(PreparedList &&other, bool cutToAlbumSize) {
if (error != Error::None) { if (error != Error::None) {
return; return;
} }
@ -375,9 +397,14 @@ void PreparedList::mergeToEnd(PreparedList &&other) {
return; return;
} }
allFilesForCompress = allFilesForCompress && other.allFilesForCompress; 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) { for (auto &file : other.files) {
files.push_back(std::move(file)); files.push_back(std::move(file));
if (cutToAlbumSize && files.size() == kMaxAlbumCount) {
break;
}
} }
if (files.size() > 1 && files.size() <= kMaxAlbumCount) { if (files.size() > 1 && files.size() <= kMaxAlbumCount) {
const auto badIt = ranges::find( const auto badIt = ranges::find(

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "core/file_utilities.h" #include "core/file_utilities.h"
#include "lang/lang_keys.h"
struct FileMediaInformation; struct FileMediaInformation;
@ -61,13 +62,12 @@ struct PreparedList {
static PreparedList Reordered( static PreparedList Reordered(
PreparedList &&list, PreparedList &&list,
std::vector<int> order); std::vector<int> order);
static std::optional<PreparedList> PreparedFileFromFileDialog( static std::optional<PreparedList> PreparedFileFromFilesDialog(
FileDialog::OpenResult &&result, FileDialog::OpenResult &&result,
bool isAlbum, bool isAlbum,
Fn<void()> errorCallback, Fn<void(tr::phrase<>)> errorCallback,
Fn<bool(QString)> isValidFileCallback,
int previewWidth); int previewWidth);
void mergeToEnd(PreparedList &&other); void mergeToEnd(PreparedList &&other, bool cutToAlbumSize = false);
bool canAddCaption(bool isAlbum, bool compressImages) const; bool canAddCaption(bool isAlbum, bool compressImages) const;