mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-04-17 04:39:47 +00:00
Correctly check media when editing files.
This commit is contained in:
parent
c4af731b19
commit
a614ccad97
@ -4228,18 +4228,11 @@ void ApiWrap::sendFiles(
|
||||
tasks.reserve(list.files.size());
|
||||
for (auto &file : list.files) {
|
||||
if (album) {
|
||||
switch (file.type) {
|
||||
case Ui::PreparedFile::AlbumType::Photo:
|
||||
type = (type == SendMediaType::File)
|
||||
? type
|
||||
: SendMediaType::Photo;
|
||||
break;
|
||||
case Ui::PreparedFile::AlbumType::Music:
|
||||
case Ui::PreparedFile::AlbumType::Video:
|
||||
case Ui::PreparedFile::AlbumType::File:
|
||||
if (file.type == Ui::PreparedFile::Type::Photo
|
||||
&& type != SendMediaType::File) {
|
||||
type = SendMediaType::Photo;
|
||||
} else {
|
||||
type = SendMediaType::File;
|
||||
break;
|
||||
default: Unexpected("AlbumType in ApiWrap::sendFiles.");
|
||||
}
|
||||
}
|
||||
tasks.push_back(std::make_unique<FileLoadTask>(
|
||||
|
@ -106,10 +106,23 @@ EditCaptionBox::EditCaptionBox(
|
||||
Expects(item->media()->allowsEditCaption());
|
||||
|
||||
_isAllowedEditMedia = item->media()->allowsEditMedia();
|
||||
_isAlbum = !item->groupId().empty();
|
||||
|
||||
auto dimensions = QSize();
|
||||
const auto media = item->media();
|
||||
|
||||
if (!item->groupId().empty()) {
|
||||
if (media->photo()) {
|
||||
_albumType = Ui::AlbumType::PhotoVideo;
|
||||
} else if (const auto document = media->document()) {
|
||||
if (document->isVideoFile()) {
|
||||
_albumType = Ui::AlbumType::PhotoVideo;
|
||||
} else if (document->isSong()) {
|
||||
_albumType = Ui::AlbumType::Music;
|
||||
} else {
|
||||
_albumType = Ui::AlbumType::File;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto photo = media->photo()) {
|
||||
_photoMedia = photo->createMediaView();
|
||||
_photoMedia->wanted(PhotoSize::Large, _msgId);
|
||||
@ -503,7 +516,8 @@ void EditCaptionBox::updateEditPreview() {
|
||||
if (const auto image = std::get_if<Info::Image>(fileMedia)) {
|
||||
shouldAsDoc = !Ui::ValidateThumbDimensions(
|
||||
image->data.width(),
|
||||
image->data.height());
|
||||
image->data.height()
|
||||
) || (_albumType == Ui::AlbumType::File);
|
||||
if (shouldAsDoc) {
|
||||
docPhotoSize.setWidth(image->data.width());
|
||||
docPhotoSize.setHeight(image->data.height());
|
||||
@ -554,7 +568,7 @@ void EditCaptionBox::updateEditPreview() {
|
||||
_doc = true;
|
||||
}
|
||||
|
||||
const auto showCheckbox = _photo && !_isAlbum;
|
||||
const auto showCheckbox = _photo && (_albumType == Ui::AlbumType::None);
|
||||
_wayWrap->toggle(showCheckbox, anim::type::instant);
|
||||
|
||||
if (!_doc) {
|
||||
@ -604,14 +618,10 @@ void EditCaptionBox::createEditMediaButton() {
|
||||
if (Core::IsMimeSticker(mime)) {
|
||||
showError(tr::lng_edit_media_invalid_file);
|
||||
return false;
|
||||
} else if (_isAlbum) { // #TODO files edit in file-albums
|
||||
if (!Core::IsMimeAcceptedForAlbum(mime)
|
||||
|| file.type == Ui::PreparedFile::AlbumType::File
|
||||
|| file.type == Ui::PreparedFile::AlbumType::Music
|
||||
|| file.type == Ui::PreparedFile::AlbumType::None) {
|
||||
showError(tr::lng_edit_media_album_error);
|
||||
return false;
|
||||
}
|
||||
} else if (_albumType != Ui::AlbumType::None
|
||||
&& !file.canBeInAlbumType(_albumType)) {
|
||||
showError(tr::lng_edit_media_album_error);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
@ -622,14 +632,13 @@ void EditCaptionBox::createEditMediaButton() {
|
||||
st::sendMediaPreviewSize);
|
||||
|
||||
if (list) {
|
||||
_preparedList = std::move(*list);
|
||||
updateEditPreview();
|
||||
setPreparedList(std::move(*list));
|
||||
}
|
||||
};
|
||||
|
||||
const auto buttonCallback = [=] {
|
||||
const auto filters = _isAlbum
|
||||
? FileDialog::AlbumFilesFilter()
|
||||
const auto filters = (_albumType == Ui::AlbumType::PhotoVideo)
|
||||
? FileDialog::PhotoVideoFilesFilter()
|
||||
: FileDialog::AllFilesFilter();
|
||||
FileDialog::GetOpenPath(
|
||||
this,
|
||||
@ -676,7 +685,7 @@ void EditCaptionBox::prepare() {
|
||||
if (action == Ui::InputField::MimeAction::Check) {
|
||||
if (!data->hasText() && !_isAllowedEditMedia) {
|
||||
return false;
|
||||
} else if (Storage::ValidateDragData(data, _isAlbum)) {
|
||||
} else if (Storage::ValidateEditMediaDragData(data, _albumType)) {
|
||||
return true;
|
||||
}
|
||||
return data->hasText();
|
||||
@ -700,40 +709,32 @@ void EditCaptionBox::prepare() {
|
||||
}
|
||||
|
||||
bool EditCaptionBox::fileFromClipboard(not_null<const QMimeData*> data) {
|
||||
return setPreparedList(ListFromMimeData(data));
|
||||
}
|
||||
|
||||
bool EditCaptionBox::setPreparedList(Ui::PreparedList &&list) {
|
||||
if (!_isAllowedEditMedia) {
|
||||
return false;
|
||||
}
|
||||
using Error = Ui::PreparedList::Error;
|
||||
using AlbumType = Ui::PreparedFile::AlbumType;
|
||||
auto list = ListFromMimeData(data);
|
||||
|
||||
using Type = Ui::PreparedFile::Type;
|
||||
if (list.error != Error::None || list.files.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto file = &list.files.front();
|
||||
if (_isAlbum && (file->type == AlbumType::File
|
||||
|| file->type == AlbumType::None
|
||||
|| file->type == AlbumType::Music)) {
|
||||
const auto imageAsDoc = [&] {
|
||||
using Info = Ui::PreparedFileInformation;
|
||||
const auto fileMedia = &file->information->media;
|
||||
if (const auto image = std::get_if<Info::Image>(fileMedia)) {
|
||||
return !Ui::ValidateThumbDimensions(
|
||||
image->data.width(),
|
||||
image->data.height());
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
|
||||
if (!data->hasText() || imageAsDoc) {
|
||||
Ui::show(
|
||||
Box<InformBox>(tr::lng_edit_media_album_error(tr::now)),
|
||||
Ui::LayerOption::KeepOther);
|
||||
auto file = &list.files.front();
|
||||
const auto invalidForAlbum = (_albumType != Ui::AlbumType::None)
|
||||
&& !file->canBeInAlbumType(_albumType);
|
||||
if (_albumType == Ui::AlbumType::PhotoVideo) {
|
||||
using Video = Ui::PreparedFileInformation::Video;
|
||||
if (const auto video = std::get_if<Video>(&file->information->media)) {
|
||||
video->isGifv = false;
|
||||
}
|
||||
}
|
||||
if (invalidForAlbum) {
|
||||
Ui::Toast::Show(tr::lng_edit_media_album_error(tr::now));
|
||||
return false;
|
||||
}
|
||||
_photo = _isImage = (file->type == AlbumType::Photo);
|
||||
_photo = _isImage = (file->type == Type::Photo);
|
||||
_preparedList = std::move(list);
|
||||
updateEditPreview();
|
||||
return true;
|
||||
@ -783,7 +784,7 @@ void EditCaptionBox::setupDragArea() {
|
||||
auto enterFilter = [=](not_null<const QMimeData*> data) {
|
||||
return !_isAllowedEditMedia
|
||||
? false
|
||||
: Storage::ValidateDragData(data, _isAlbum);
|
||||
: Storage::ValidateEditMediaDragData(data, _albumType);
|
||||
};
|
||||
// Avoid both drag areas appearing at one time.
|
||||
auto computeState = [=](const QMimeData *data) {
|
||||
|
@ -33,6 +33,7 @@ class InputField;
|
||||
class EmojiButton;
|
||||
class IconButton;
|
||||
class Checkbox;
|
||||
enum class AlbumType;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
@ -93,6 +94,7 @@ private:
|
||||
int errorTopSkip() const;
|
||||
|
||||
void createEditMediaButton();
|
||||
bool setPreparedList(Ui::PreparedList &&list);
|
||||
|
||||
inline QString getNewMediaPath() {
|
||||
return _preparedList.files.empty()
|
||||
@ -138,8 +140,8 @@ private:
|
||||
object_ptr<Ui::IconButton> _editMedia = nullptr;
|
||||
Ui::SlideWrap<Ui::RpWidget> *_wayWrap = nullptr;
|
||||
QString _newMediaPath;
|
||||
Ui::AlbumType _albumType = Ui::AlbumType();
|
||||
bool _isAllowedEditMedia = false;
|
||||
bool _isAlbum = false;
|
||||
bool _asFile = false;
|
||||
rpl::event_stream<> _editMediaClicks;
|
||||
|
||||
|
@ -473,7 +473,7 @@ void SendFilesBox::preparePreview() {
|
||||
void SendFilesBox::generatePreviewFrom(int fromBlock) {
|
||||
Expects(fromBlock <= _blocks.size());
|
||||
|
||||
using Type = Ui::PreparedFile::AlbumType;
|
||||
using Type = Ui::PreparedFile::Type;
|
||||
|
||||
const auto eraseFrom = _blocks.begin() + fromBlock;
|
||||
for (auto i = eraseFrom; i != _blocks.end(); ++i) {
|
||||
@ -813,7 +813,7 @@ void SendFilesBox::refreshTitleText() {
|
||||
if (count > 1) {
|
||||
const auto imagesCount = ranges::count(
|
||||
_list.files,
|
||||
Ui::PreparedFile::AlbumType::Photo,
|
||||
Ui::PreparedFile::Type::Photo,
|
||||
&Ui::PreparedFile::type);
|
||||
_titleText = (imagesCount == count)
|
||||
? tr::lng_send_images_selected(tr::now, lt_count, count)
|
||||
|
@ -329,8 +329,9 @@ QString ImagesOrAllFilter() {
|
||||
return ImagesFilter() + u";;"_q + AllFilesFilter();
|
||||
}
|
||||
|
||||
QString AlbumFilesFilter() {
|
||||
return u"Image and Video Files (*.png *.jpg *.jpeg *.mp4 *.mov)"_q;
|
||||
QString PhotoVideoFilesFilter() {
|
||||
return u"Image and Video Files (*.png *.jpg *.jpeg *.mp4 *.mov);;"_q
|
||||
+ AllFilesFilter();
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
@ -93,7 +93,7 @@ void GetFolder(
|
||||
[[nodiscard]] QString ImagesFilter();
|
||||
[[nodiscard]] QString AllOrImagesFilter();
|
||||
[[nodiscard]] QString ImagesOrAllFilter();
|
||||
[[nodiscard]] QString AlbumFilesFilter();
|
||||
[[nodiscard]] QString PhotoVideoFilesFilter();
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
@ -111,7 +111,7 @@ bool IsMimeSticker(const QString &mime) {
|
||||
|| IsMimeStickerAnimated(mime);
|
||||
}
|
||||
|
||||
bool IsMimeAcceptedForAlbum(const QString &mime) {
|
||||
bool IsMimeAcceptedForPhotoVideoAlbum(const QString &mime) {
|
||||
return (mime == u"image/jpeg"_q)
|
||||
|| (mime == u"image/png"_q)
|
||||
|| (mime == u"video/mp4"_q)
|
||||
|
@ -42,7 +42,7 @@ private:
|
||||
|
||||
[[nodiscard]] bool IsMimeStickerAnimated(const QString &mime);
|
||||
[[nodiscard]] bool IsMimeSticker(const QString &mime);
|
||||
[[nodiscard]] bool IsMimeAcceptedForAlbum(const QString &mime);
|
||||
[[nodiscard]] bool IsMimeAcceptedForPhotoVideoAlbum(const QString &mime);
|
||||
|
||||
[[nodiscard]] bool FileIsImage(const QString &name, const QString &mime);
|
||||
|
||||
|
@ -4226,14 +4226,15 @@ void HistoryWidget::sendingFilesConfirmed(
|
||||
action.replyTo = replyToId();
|
||||
action.options = options;
|
||||
action.clearDraft = false;
|
||||
if ((groups.empty() || groups.size() > 1) && !caption.text.isEmpty()) {
|
||||
if ((groups.size() != 1 || !groups.front().sentWithCaption())
|
||||
&& !caption.text.isEmpty()) {
|
||||
auto message = Api::MessageToSend(_history);
|
||||
message.textWithTags = base::take(caption);
|
||||
message.action = action;
|
||||
session().api().sendMessage(std::move(message));
|
||||
}
|
||||
for (auto &group : groups) {
|
||||
const auto album = group.grouped
|
||||
const auto album = (group.type != Ui::AlbumType::None)
|
||||
? std::make_shared<SendingAlbum>()
|
||||
: nullptr;
|
||||
session().api().sendFiles(
|
||||
|
@ -671,14 +671,15 @@ void RepliesWidget::sendingFilesConfirmed(
|
||||
action.replyTo = replyTo ? replyTo : _rootId;
|
||||
action.options = options;
|
||||
action.clearDraft = false;
|
||||
if ((groups.empty() || groups.size() > 1) && !caption.text.isEmpty()) {
|
||||
if ((groups.size() != 1 || !groups.front().sentWithCaption())
|
||||
&& !caption.text.isEmpty()) {
|
||||
auto message = Api::MessageToSend(_history);
|
||||
message.textWithTags = base::take(caption);
|
||||
message.action = action;
|
||||
session().api().sendMessage(std::move(message));
|
||||
}
|
||||
for (auto &group : groups) {
|
||||
const auto album = group.grouped
|
||||
const auto album = (group.type != Ui::AlbumType::None)
|
||||
? std::make_shared<SendingAlbum>()
|
||||
: nullptr;
|
||||
session().api().sendFiles(
|
||||
|
@ -407,14 +407,15 @@ void ScheduledWidget::sendingFilesConfirmed(
|
||||
auto action = Api::SendAction(_history);
|
||||
action.options = options;
|
||||
action.clearDraft = false;
|
||||
if ((groups.empty() || groups.size() > 1) && !caption.text.isEmpty()) {
|
||||
if ((groups.size() != 1 || !groups.front().sentWithCaption())
|
||||
&& !caption.text.isEmpty()) {
|
||||
auto message = Api::MessageToSend(_history);
|
||||
message.textWithTags = base::take(caption);
|
||||
message.action = action;
|
||||
session().api().sendMessage(std::move(message));
|
||||
}
|
||||
for (auto &group : groups) {
|
||||
const auto album = group.grouped
|
||||
const auto album = (group.type != Ui::AlbumType::None)
|
||||
? std::make_shared<SendingAlbum>()
|
||||
: nullptr;
|
||||
session().api().sendFiles(
|
||||
|
@ -80,19 +80,21 @@ void PrepareDetailsInParallel(PreparedList &result, int previewWidth) {
|
||||
|
||||
} // namespace
|
||||
|
||||
bool ValidateDragData(not_null<const QMimeData*> data, bool isAlbum) {
|
||||
bool ValidateEditMediaDragData(
|
||||
not_null<const QMimeData*> data,
|
||||
Ui::AlbumType albumType) {
|
||||
if (data->urls().size() > 1) {
|
||||
return false;
|
||||
} else if (data->hasImage()) {
|
||||
return true;
|
||||
return (albumType != Ui::AlbumType::Music);
|
||||
}
|
||||
|
||||
if (isAlbum && data->hasUrls()) {
|
||||
if (albumType == Ui::AlbumType::PhotoVideo && data->hasUrls()) {
|
||||
const auto url = data->urls().front();
|
||||
if (url.isLocalFile()) {
|
||||
using namespace Core;
|
||||
const auto info = QFileInfo(Platform::File::UrlToLocal(url));
|
||||
return IsMimeAcceptedForAlbum(MimeTypeForFile(info).name());
|
||||
return IsMimeAcceptedForPhotoVideoAlbum(MimeTypeForFile(info).name());
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,86 +243,6 @@ std::optional<PreparedList> PreparedFileFromFilesDialog(
|
||||
} else {
|
||||
return list;
|
||||
}
|
||||
//if (!result.remoteContent.isEmpty()) {
|
||||
// auto list = PrepareMediaFromImage(
|
||||
// QImage(),
|
||||
// std::move(result.remoteContent),
|
||||
// previewWidth);
|
||||
|
||||
// const auto mimeFile = list.files.front().information->filemime;
|
||||
// if (Core::IsMimeSticker(mimeFile)) {
|
||||
// errorCallback(tr::lng_edit_media_invalid_file);
|
||||
// return std::nullopt;
|
||||
// }
|
||||
|
||||
// if (isAlbum) {
|
||||
// const auto file = &list.files.front();
|
||||
// if (!Core::IsMimeAcceptedForAlbum(mimeFile)
|
||||
// || file->type == PreparedFile::AlbumType::File
|
||||
// || file->type == PreparedFile::AlbumType::Music
|
||||
// || file->type == PreparedFile::AlbumType::None) {
|
||||
// errorCallback(tr::lng_edit_media_album_error);
|
||||
// return std::nullopt;
|
||||
// }
|
||||
// }
|
||||
|
||||
// Ensures(list.files.size() == 1);
|
||||
// return list;
|
||||
//} else if (!result.paths.isEmpty()) {
|
||||
// auto temp = PrepareMediaList(result.paths, previewWidth);
|
||||
// const auto isSingleFile = (temp.files.size() == 1);
|
||||
// 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) {
|
||||
// const auto info = QFileInfo(file.path);
|
||||
// if (Core::IsMimeSticker(Core::MimeTypeForFile(info).name())) {
|
||||
// if (isSingleFile) {
|
||||
// errorCallback(tr::lng_edit_media_invalid_file);
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
// if (!isAlbum) {
|
||||
// return true;
|
||||
// }
|
||||
// using Info = PreparedFileInformation;
|
||||
|
||||
// const auto media = &file.information->media;
|
||||
// const auto valid = v::match(*media, [](const Info::Image &data) {
|
||||
// return Ui::ValidateThumbDimensions(
|
||||
// data.data.width(),
|
||||
// data.data.height())
|
||||
// && !data.animated;
|
||||
// }, [](Info::Video &data) {
|
||||
// data.isGifv = false;
|
||||
// return true;
|
||||
// }, [](auto &&other) {
|
||||
// return false;
|
||||
// });
|
||||
// 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);
|
||||
// }
|
||||
// return std::nullopt;
|
||||
// }
|
||||
|
||||
// auto list = PreparedList(temp.error, temp.errorData);
|
||||
// list.files = std::move(filteredFiles);
|
||||
|
||||
// return list;
|
||||
//}
|
||||
//return std::nullopt;
|
||||
}
|
||||
|
||||
void PrepareDetails(PreparedFile &file, int previewWidth) {
|
||||
@ -351,9 +273,9 @@ void PrepareDetails(PreparedFile &file, int previewWidth) {
|
||||
Qt::SmoothTransformation));
|
||||
Assert(!file.preview.isNull());
|
||||
file.preview.setDevicePixelRatio(cRetinaFactor());
|
||||
file.type = PreparedFile::AlbumType::Photo;
|
||||
file.type = PreparedFile::Type::Photo;
|
||||
} else if (Core::IsMimeSticker(file.information->filemime)) {
|
||||
file.type = PreparedFile::AlbumType::None;
|
||||
file.type = PreparedFile::Type::None;
|
||||
}
|
||||
} else if (const auto video = std::get_if<Video>(
|
||||
&file.information->media)) {
|
||||
@ -365,10 +287,10 @@ void PrepareDetails(PreparedFile &file, int previewWidth) {
|
||||
Qt::SmoothTransformation);
|
||||
Assert(!file.preview.isNull());
|
||||
file.preview.setDevicePixelRatio(cRetinaFactor());
|
||||
file.type = PreparedFile::AlbumType::Video;
|
||||
file.type = PreparedFile::Type::Video;
|
||||
}
|
||||
} else if (const auto song = std::get_if<Song>(&file.information->media)) {
|
||||
file.type = PreparedFile::AlbumType::Music;
|
||||
file.type = PreparedFile::Type::Music;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ namespace Ui {
|
||||
struct PreparedFileInformation;
|
||||
struct PreparedFile;
|
||||
struct PreparedList;
|
||||
enum class AlbumType;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Storage {
|
||||
@ -31,7 +32,9 @@ std::optional<Ui::PreparedList> PreparedFileFromFilesDialog(
|
||||
Fn<void(tr::phrase<>)> errorCallback,
|
||||
int previewWidth);
|
||||
MimeDataState ComputeMimeDataState(const QMimeData *data);
|
||||
bool ValidateDragData(not_null<const QMimeData*> data, bool isAlbum);
|
||||
bool ValidateEditMediaDragData(
|
||||
not_null<const QMimeData*> data,
|
||||
Ui::AlbumType albumType);
|
||||
Ui::PreparedList PrepareMediaList(const QList<QUrl> &files, int previewWidth);
|
||||
Ui::PreparedList PrepareMediaList(const QStringList &files, int previewWidth);
|
||||
Ui::PreparedList PrepareMediaFromImage(
|
||||
|
@ -29,7 +29,7 @@ AlbumThumbnail::AlbumThumbnail(
|
||||
: _layout(layout)
|
||||
, _fullPreview(file.preview)
|
||||
, _shrinkSize(int(std::ceil(st::historyMessageRadius / 1.4)))
|
||||
, _isVideo(file.type == PreparedFile::AlbumType::Video)
|
||||
, _isVideo(file.type == PreparedFile::Type::Video)
|
||||
, _buttonsRect(st::sendBoxAlbumGroupRadius, st::callFingerprintBg) {
|
||||
Expects(!_fullPreview.isNull());
|
||||
|
||||
|
@ -26,6 +26,41 @@ PreparedFile &PreparedFile::operator=(PreparedFile &&other) = default;
|
||||
|
||||
PreparedFile::~PreparedFile() = default;
|
||||
|
||||
bool PreparedFile::canBeInAlbumType(AlbumType album) const {
|
||||
return CanBeInAlbumType(type, album);
|
||||
}
|
||||
|
||||
AlbumType PreparedFile::albumType(bool sendImagesAsPhotos) const {
|
||||
switch (type) {
|
||||
case Type::Photo:
|
||||
return sendImagesAsPhotos ? AlbumType::PhotoVideo : AlbumType::File;
|
||||
case Type::Video:
|
||||
return AlbumType::PhotoVideo;
|
||||
case Type::Music:
|
||||
return AlbumType::Music;
|
||||
case Type::File:
|
||||
return AlbumType::File;
|
||||
case Type::None:
|
||||
return AlbumType::None;
|
||||
}
|
||||
Unexpected("PreparedFile::type in PreparedFile::albumType().");
|
||||
}
|
||||
|
||||
bool CanBeInAlbumType(PreparedFile::Type type, AlbumType album) {
|
||||
Expects(album != AlbumType::None);
|
||||
|
||||
using Type = PreparedFile::Type;
|
||||
switch (album) {
|
||||
case AlbumType::PhotoVideo:
|
||||
return (type == Type::Photo) || (type == Type::Video);
|
||||
case AlbumType::Music:
|
||||
return (type == Type::Music);
|
||||
case AlbumType::File:
|
||||
return (type == Type::Photo) || (type == Type::File);
|
||||
}
|
||||
Unexpected("AlbumType in CanBeInAlbumType.");
|
||||
}
|
||||
|
||||
PreparedList PreparedList::Reordered(
|
||||
PreparedList &&list,
|
||||
std::vector<int> order) {
|
||||
@ -73,7 +108,7 @@ bool PreparedList::canBeSentInSlowmodeWith(const PreparedList &other) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
using Type = PreparedFile::AlbumType;
|
||||
using Type = PreparedFile::Type;
|
||||
auto &&all = ranges::view::concat(files, other.files);
|
||||
const auto has = [&](Type type) {
|
||||
return ranges::contains(all, type, &PreparedFile::type);
|
||||
@ -117,11 +152,11 @@ bool PreparedList::canAddCaption(bool sendingAlbum) const {
|
||||
}
|
||||
const auto hasFiles = ranges::contains(
|
||||
files,
|
||||
PreparedFile::AlbumType::File,
|
||||
PreparedFile::Type::File,
|
||||
&PreparedFile::type);
|
||||
const auto hasNotGrouped = ranges::contains(
|
||||
files,
|
||||
PreparedFile::AlbumType::None,
|
||||
PreparedFile::Type::None,
|
||||
&PreparedFile::type);
|
||||
return !hasFiles && !hasNotGrouped;
|
||||
}
|
||||
@ -130,7 +165,7 @@ bool PreparedList::hasGroupOption(bool slowmode) const {
|
||||
if (slowmode || files.size() < 2) {
|
||||
return false;
|
||||
}
|
||||
using Type = PreparedFile::AlbumType;
|
||||
using Type = PreparedFile::Type;
|
||||
auto lastType = Type::None;
|
||||
for (const auto &file : files) {
|
||||
if ((file.type == lastType)
|
||||
@ -148,7 +183,7 @@ bool PreparedList::hasGroupOption(bool slowmode) const {
|
||||
}
|
||||
|
||||
bool PreparedList::hasSendImagesAsPhotosOption(bool slowmode) const {
|
||||
using Type = PreparedFile::AlbumType;
|
||||
using Type = PreparedFile::Type;
|
||||
return slowmode
|
||||
? ((files.size() == 1) && (files.front().type == Type::Photo))
|
||||
: ranges::contains(files, Type::Photo, &PreparedFile::type);
|
||||
@ -174,42 +209,33 @@ std::vector<PreparedGroup> DivideByGroups(
|
||||
|
||||
auto group = Ui::PreparedList();
|
||||
|
||||
enum class GroupType {
|
||||
PhotoVideo,
|
||||
File,
|
||||
Music,
|
||||
None,
|
||||
};
|
||||
// For groupType Type::Video means media album,
|
||||
// Type::File means file album,
|
||||
// Type::None means no grouping.
|
||||
using Type = Ui::PreparedFile::AlbumType;
|
||||
auto groupType = GroupType::None;
|
||||
using Type = Ui::PreparedFile::Type;
|
||||
auto groupType = AlbumType::None;
|
||||
|
||||
auto result = std::vector<PreparedGroup>();
|
||||
auto pushGroup = [&] {
|
||||
result.push_back(PreparedGroup{
|
||||
.list = base::take(group),
|
||||
.grouped = (groupType != GroupType::None)
|
||||
.type = groupType,
|
||||
});
|
||||
};
|
||||
for (auto i = 0; i != list.files.size(); ++i) {
|
||||
auto &file = list.files[i];
|
||||
const auto fileGroupType = (file.type == Type::Music)
|
||||
? (groupFiles ? GroupType::Music : GroupType::None)
|
||||
? (groupFiles ? AlbumType::Music : AlbumType::None)
|
||||
: (file.type == Type::Video)
|
||||
? (groupFiles ? GroupType::PhotoVideo : GroupType::None)
|
||||
? (groupFiles ? AlbumType::PhotoVideo : AlbumType::None)
|
||||
: (file.type == Type::Photo)
|
||||
? ((groupFiles && sendImagesAsPhotos)
|
||||
? GroupType::PhotoVideo
|
||||
? AlbumType::PhotoVideo
|
||||
: (groupFiles && !sendImagesAsPhotos)
|
||||
? GroupType::File
|
||||
: GroupType::None)
|
||||
? AlbumType::File
|
||||
: AlbumType::None)
|
||||
: (file.type == Type::File)
|
||||
? (groupFiles ? GroupType::File : GroupType::None)
|
||||
: GroupType::None;
|
||||
? (groupFiles ? AlbumType::File : AlbumType::None)
|
||||
: AlbumType::None;
|
||||
if ((!group.files.empty() && groupType != fileGroupType)
|
||||
|| ((groupType != GroupType::None)
|
||||
|| ((groupType != AlbumType::None)
|
||||
&& (group.files.size() == Ui::MaxAlbumItems()))) {
|
||||
pushGroup();
|
||||
}
|
||||
|
@ -36,6 +36,13 @@ struct PreparedFileInformation {
|
||||
std::variant<v::null_t, Image, Song, Video> media;
|
||||
};
|
||||
|
||||
enum class AlbumType {
|
||||
None,
|
||||
PhotoVideo,
|
||||
Music,
|
||||
File,
|
||||
};
|
||||
|
||||
struct PreparedFile {
|
||||
// File-s can be grouped if 'groupFiles'.
|
||||
// File-s + Photo-s can be grouped if 'groupFiles && !sendImagesAsPhotos'.
|
||||
@ -43,12 +50,12 @@ struct PreparedFile {
|
||||
// Photo-s + Video-s can be grouped if 'groupFiles && sendImagesAsPhotos'.
|
||||
// Video-s can be grouped if 'groupFiles'.
|
||||
// Music-s can be grouped if 'groupFiles'.
|
||||
enum class AlbumType {
|
||||
File,
|
||||
enum class Type {
|
||||
None,
|
||||
Photo,
|
||||
Video,
|
||||
Music,
|
||||
None,
|
||||
File,
|
||||
};
|
||||
|
||||
PreparedFile(const QString &path);
|
||||
@ -56,15 +63,20 @@ struct PreparedFile {
|
||||
PreparedFile &operator=(PreparedFile &&other);
|
||||
~PreparedFile();
|
||||
|
||||
[[nodiscard]] bool canBeInAlbumType(AlbumType album) const;
|
||||
[[nodiscard]] AlbumType albumType(bool sendImagesAsPhotos) const;
|
||||
|
||||
QString path;
|
||||
QByteArray content;
|
||||
int size = 0;
|
||||
std::unique_ptr<Ui::PreparedFileInformation> information;
|
||||
QImage preview;
|
||||
QSize shownDimensions;
|
||||
AlbumType type = AlbumType::File;
|
||||
Type type = Type::File;
|
||||
};
|
||||
|
||||
[[nodiscard]] bool CanBeInAlbumType(PreparedFile::Type type, AlbumType album);
|
||||
|
||||
struct PreparedList {
|
||||
enum class Error {
|
||||
None,
|
||||
@ -104,7 +116,12 @@ struct PreparedList {
|
||||
|
||||
struct PreparedGroup {
|
||||
PreparedList list;
|
||||
bool grouped = false;
|
||||
AlbumType type = AlbumType::None;
|
||||
|
||||
[[nodiscard]] bool sentWithCaption() const {
|
||||
return (list.files.size() == 1)
|
||||
|| (type == AlbumType::PhotoVideo);
|
||||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] std::vector<PreparedGroup> DivideByGroups(
|
||||
|
Loading…
Reference in New Issue
Block a user