mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-04-01 00:08:02 +00:00
Implemented ability to add more than 1 file to albums via SendFilesBox.
This commit is contained in:
parent
a482b744d2
commit
e266dc153b
@ -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 :(";
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
|
@ -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(
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user