diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index bf038ffe00..afe7639d35 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -4234,6 +4234,7 @@ void ApiWrap::sendFiles( ? type : SendMediaType::Photo; break; + case Ui::PreparedFile::AlbumType::Music: case Ui::PreparedFile::AlbumType::Video: case Ui::PreparedFile::AlbumType::File: type = SendMediaType::File; diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index b3a853eafd..99cf59946e 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -603,9 +603,10 @@ void EditCaptionBox::createEditMediaButton() { if (Core::IsMimeSticker(mime)) { showError(tr::lng_edit_media_invalid_file); return false; - } else if (_isAlbum) { // #TODO edit in file-albums + } 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; @@ -710,7 +711,9 @@ bool EditCaptionBox::fileFromClipboard(not_null data) { } const auto file = &list.files.front(); - if (_isAlbum && (file->type == AlbumType::File || file->type == AlbumType::None)) { + 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; diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 91f158b76b..6ce610629c 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -118,8 +118,7 @@ SendFilesBox::Block::Block( const auto count = till - from; const auto my = gsl::make_span(*items).subspan(from, count); const auto &first = my.front(); - _isAlbum = (my.size() > 1) - || (first.type == Ui::PreparedFile::AlbumType::Photo); + _isAlbum = (my.size() > 1); if (_isAlbum) { const auto preview = Ui::CreateChild( parent.get(), @@ -492,6 +491,7 @@ void SendFilesBox::generatePreviewFrom(int fromBlock) { const auto albumCount = (i - albumStart); if ((type == Type::File) || (type == Type::None) + || (type == Type::Music) || (albumCount == Ui::MaxAlbumItems())) { pushBlock(std::exchange(albumStart, -1), i); } else { diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index a4784561b2..cd236d62f5 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -1508,10 +1508,7 @@ bool DocumentData::isAudioFile() const { } bool DocumentData::isSharedMediaMusic() const { - if (const auto songData = song()) { - return (songData->duration > 0); - } - return false; + return isSong(); } bool DocumentData::isVideoFile() const { diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.cpp b/Telegram/SourceFiles/storage/storage_media_prepare.cpp index b156e7d8b0..6251c54090 100644 --- a/Telegram/SourceFiles/storage/storage_media_prepare.cpp +++ b/Telegram/SourceFiles/storage/storage_media_prepare.cpp @@ -257,6 +257,7 @@ std::optional PreparedFileFromFilesDialog( // 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; @@ -339,6 +340,7 @@ void PrepareDetails(PreparedFile &file, int previewWidth) { using Image = PreparedFileInformation::Image; using Video = PreparedFileInformation::Video; + using Song = PreparedFileInformation::Song; if (const auto image = std::get_if( &file.information->media)) { if (ValidPhotoForAlbum(*image, file.information->filemime)) { @@ -365,6 +367,8 @@ void PrepareDetails(PreparedFile &file, int previewWidth) { file.preview.setDevicePixelRatio(cRetinaFactor()); file.type = PreparedFile::AlbumType::Video; } + } else if (const auto song = std::get_if(&file.information->media)) { + file.type = PreparedFile::AlbumType::Music; } } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp index d79be2777a..220d65c1a4 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp @@ -73,21 +73,28 @@ bool PreparedList::canBeSentInSlowmodeWith(const PreparedList &other) const { return false; } + using Type = PreparedFile::AlbumType; auto &&all = ranges::view::concat(files, other.files); - const auto hasNonGrouping = ranges::contains( - all, - PreparedFile::AlbumType::None, - &PreparedFile::type); - const auto hasFiles = ranges::contains( - all, - PreparedFile::AlbumType::File, - &PreparedFile::type); - const auto hasVideos = ranges::contains( - all, - PreparedFile::AlbumType::Video, - &PreparedFile::type); + const auto has = [&](Type type) { + return ranges::contains(all, type, &PreparedFile::type); + }; + const auto hasNonGrouping = has(Type::None); + const auto hasPhotos = has(Type::Photo); + const auto hasFiles = has(Type::File); + const auto hasVideos = has(Type::Video); + const auto hasMusic = has(Type::Music); // File-s and Video-s never can be grouped. + // Music-s can be grouped only with themselves. + if (hasNonGrouping) { + return false; + } else if (hasFiles) { + return !hasMusic && !hasVideos; + } else if (hasVideos) { + return !hasMusic && !hasFiles; + } else if (hasMusic) { + return !hasVideos && !hasFiles && !hasPhotos; + } return !hasNonGrouping && (!hasFiles || !hasVideos); } @@ -139,34 +146,42 @@ std::vector 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 = Type::None; + auto groupType = GroupType::None; auto result = std::vector(); auto pushGroup = [&] { result.push_back(PreparedGroup{ .list = base::take(group), - .grouped = (groupType != Type::None) + .grouped = (groupType != GroupType::None) }); }; for (auto i = 0; i != list.files.size(); ++i) { auto &file = list.files[i]; - const auto fileGroupType = (file.type == Type::Video) - ? (groupFiles ? Type::Video : Type::None) + const auto fileGroupType = (file.type == Type::Music) + ? (groupFiles ? GroupType::Music : GroupType::None) + : (file.type == Type::Video) + ? (groupFiles ? GroupType::PhotoVideo : GroupType::None) : (file.type == Type::Photo) ? ((groupFiles && sendImagesAsPhotos) - ? Type::Video + ? GroupType::PhotoVideo : (groupFiles && !sendImagesAsPhotos) - ? Type::File - : Type::None) + ? GroupType::File + : GroupType::None) : (file.type == Type::File) - ? (groupFiles ? Type::File : Type::None) - : Type::None; + ? (groupFiles ? GroupType::File : GroupType::None) + : GroupType::None; if ((!group.files.empty() && groupType != fileGroupType) - || ((groupType != Type::None) + || ((groupType != GroupType::None) && (group.files.size() == Ui::MaxAlbumItems()))) { pushGroup(); } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h index b4f5bc4945..94146796d8 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h @@ -42,10 +42,12 @@ struct PreparedFile { // Photo-s can be grouped if 'groupFiles'. // 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, Photo, Video, + Music, None, };