diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 9f82ba51c6..bf038ffe00 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -4212,14 +4212,12 @@ void ApiWrap::sendFiles( std::shared_ptr album, const SendAction &action) { const auto haveCaption = !caption.text.isEmpty(); - const auto isAlbum = (album != nullptr); - if (haveCaption && !list.canAddCaption(isAlbum)) { + if (haveCaption && !list.canAddCaption(album != nullptr)) { auto message = MessageToSend(action.history); - message.textWithTags = std::move(caption); + message.textWithTags = base::take(caption); message.action = action; message.action.clearDraft = false; sendMessage(std::move(message)); - caption = TextWithTags(); } const auto to = fileLoadTaskOptions(action); @@ -4240,7 +4238,7 @@ void ApiWrap::sendFiles( case Ui::PreparedFile::AlbumType::File: type = SendMediaType::File; break; - default: Unexpected("AlbumType in uploadFilesAfterConfirmation"); + default: Unexpected("AlbumType in ApiWrap::sendFiles."); } } tasks.push_back(std::make_unique( diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 649d414d3f..b0d0701273 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -94,7 +94,7 @@ void FileDialogCallback( rpl::producer FieldPlaceholder( const Ui::PreparedList &list, SendFilesWay way) { - return list.canAddCaption(way.groupMediaInAlbums()) + return list.canAddCaption(way.groupFiles() && way.sendImagesAsPhotos()) ? tr::lng_photo_caption() : tr::lng_photos_comment(); } @@ -436,7 +436,6 @@ void SendFilesBox::initSendWay() { _sendWay = [&] { auto result = Core::App().settings().sendFilesWay(); if (_sendLimit == SendLimit::One) { - result.setGroupMediaInAlbums(true); result.setGroupFiles(true); return result; } else if (_list.overrideSendImagesAsPhotos == false) { @@ -463,15 +462,15 @@ void SendFilesBox::updateCaptionPlaceholder() { if (!_caption) { return; } - const auto sendWay = _sendWay.current(); - if (!_list.canAddCaption(sendWay.groupMediaInAlbums()) + const auto way = _sendWay.current(); + if (!_list.canAddCaption(way.groupFiles() && way.sendImagesAsPhotos()) && _sendLimit == SendLimit::One) { _caption->hide(); if (_emojiToggle) { _emojiToggle->hide(); } } else { - _caption->setPlaceholder(FieldPlaceholder(_list, sendWay)); + _caption->setPlaceholder(FieldPlaceholder(_list, way)); _caption->show(); if (_emojiToggle) { _emojiToggle->show(); @@ -544,33 +543,27 @@ void SendFilesBox::refreshControls() { void SendFilesBox::setupSendWayControls() { // #TODO files - _groupMediaInAlbums.create( + _groupFiles.create( this, - "Group media in albums", - _sendWay.current().groupMediaInAlbums(), + "Group items", + _sendWay.current().groupFiles(), st::defaultBoxCheckbox); _sendImagesAsPhotos.create( this, - "Send images as photos", + "Compress images", _sendWay.current().sendImagesAsPhotos(), st::defaultBoxCheckbox); - _groupFiles.create( - this, - "Group files", - _sendWay.current().groupFiles(), - st::defaultBoxCheckbox); _sendWay.changes( ) | rpl::start_with_next([=](SendFilesWay value) { - _groupMediaInAlbums->setChecked(value.groupMediaInAlbums()); - _sendImagesAsPhotos->setChecked(value.sendImagesAsPhotos()); _groupFiles->setChecked(value.groupFiles()); + _sendImagesAsPhotos->setChecked(value.sendImagesAsPhotos()); }, lifetime()); - _groupMediaInAlbums->checkedChanges( + _groupFiles->checkedChanges( ) | rpl::start_with_next([=] { auto sendWay = _sendWay.current(); - sendWay.setGroupMediaInAlbums(_groupMediaInAlbums->checked()); + sendWay.setGroupFiles(_groupFiles->checked()); _sendWay = sendWay; }, lifetime()); @@ -580,13 +573,6 @@ void SendFilesBox::setupSendWayControls() { sendWay.setSendImagesAsPhotos(_sendImagesAsPhotos->checked()); _sendWay = sendWay; }, lifetime()); - - _groupFiles->checkedChanges( - ) | rpl::start_with_next([=] { - auto sendWay = _sendWay.current(); - sendWay.setGroupFiles(_groupFiles->checked()); - _sendWay = sendWay; - }, lifetime()); } void SendFilesBox::updateSendWayControlsVisibility() { @@ -594,9 +580,8 @@ void SendFilesBox::updateSendWayControlsVisibility() { return; } const auto onlyOne = (_sendLimit == SendLimit::One); - _groupMediaInAlbums->setVisible(!onlyOne); - _sendImagesAsPhotos->setVisible(/*_list.hasImagesForCompression()*/true); // #TODO files _groupFiles->setVisible(!onlyOne); + _sendImagesAsPhotos->setVisible(/*_list.hasImagesForCompression()*/true); // #TODO files } void SendFilesBox::setupCaption() { @@ -798,9 +783,8 @@ void SendFilesBox::updateBoxSize() { footerHeight += st::boxPhotoCaptionSkip + _caption->height(); } const auto pointers = { - _groupMediaInAlbums.data(), + _groupFiles.data(), _sendImagesAsPhotos.data(), - _groupFiles.data() }; for (auto pointer : pointers) { if (pointer && !pointer->isHidden()) { @@ -864,9 +848,8 @@ void SendFilesBox::updateControlsGeometry() { } } const auto pointers = { - _groupMediaInAlbums.data(), + _groupFiles.data(), _sendImagesAsPhotos.data(), - _groupFiles.data() }; for (const auto pointer : ranges::view::reverse(pointers)) { if (pointer && !pointer->isHidden()) { @@ -905,16 +888,13 @@ void SendFilesBox::send( auto way = _sendWay.current(); auto oldWay = Core::App().settings().sendFilesWay(); + if (_groupFiles->isHidden()) { + way.setGroupFiles(oldWay.groupFiles()); + } if (_list.overrideSendImagesAsPhotos == way.sendImagesAsPhotos() || _sendImagesAsPhotos->isHidden()) { way.setSendImagesAsPhotos(oldWay.sendImagesAsPhotos()); } - if (_groupMediaInAlbums->isHidden()) { - way.setGroupMediaInAlbums(oldWay.groupMediaInAlbums()); - } - if (_groupFiles->isHidden()) { - way.setGroupFiles(oldWay.groupFiles()); - } if (way != oldWay) { Core::App().settings().setSendFilesWay(way); Core::App().saveSettingsDelayed(); diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index 25384cdf66..2384852795 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -176,9 +176,8 @@ private: base::unique_qptr _emojiPanel; base::unique_qptr _emojiFilter; - object_ptr _groupMediaInAlbums = { nullptr }; - object_ptr _sendImagesAsPhotos = { nullptr }; object_ptr _groupFiles = { nullptr }; + object_ptr _sendImagesAsPhotos = { nullptr }; rpl::variable _sendWay = Ui::SendFilesWay(); rpl::variable _footerHeight = 0; @@ -190,8 +189,6 @@ private: Fn _whenReadySend; bool _preparing = false; - int _lastScrollTop = 0; - QPointer _send; QPointer _addFile; diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index c6f3e5d550..c77a230b09 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -4215,60 +4215,34 @@ void HistoryWidget::sendingFilesConfirmed( if (showSendingFilesError(list)) { return; } - const auto slowmode = _peer->slowmodeApplied(); - const auto sendImagesAsPhotos = way.sendImagesAsPhotos(); - const auto sendType = sendImagesAsPhotos + auto groups = DivideByGroups( + std::move(list), + way, + _peer->slowmodeApplied()); + const auto type = way.sendImagesAsPhotos() ? SendMediaType::Photo : SendMediaType::File; - const auto groupMedia = way.groupMediaInAlbums() || slowmode; - const auto groupFiles = way.groupFiles() || slowmode; - - auto group = Ui::PreparedList(); - - // 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; - - const auto reply = replyToId(); - auto sendGroup = [&] { - if (group.files.empty()) { - return; - } - const auto album = (groupType == Type::None) - ? nullptr - : std::make_shared(); - uploadFilesAfterConfirmation( - base::take(group), - sendType, - base::take(caption), - reply, - options, - std::move(album)); - }; - for (auto i = 0; i != list.files.size(); ++i) { - auto &file = list.files[i]; - const auto fileGroupType = (file.type == Type::Video) - ? (groupMedia ? Type::Video : Type::None) - : (file.type == Type::Photo) - ? ((groupMedia && sendImagesAsPhotos) - ? Type::Video - : (groupFiles && !sendImagesAsPhotos) - ? Type::File - : Type::None) - : (file.type == Type::File) - ? (groupFiles ? Type::File : Type::None) - : Type::None; - if ((!group.files.empty() && groupType != fileGroupType) - || ((groupType != Type::None) - && (group.files.size() == Ui::MaxAlbumItems()))) { - sendGroup(); - } - group.files.push_back(std::move(file)); - groupType = fileGroupType; + auto action = Api::SendAction(_history); + action.replyTo = replyToId(); + action.options = options; + action.clearDraft = false; + if (groups.size() > 1 && !caption.text.isEmpty()) { + auto message = Api::MessageToSend(_history); + message.textWithTags = base::take(caption); + message.action = action; + session().api().sendMessage(std::move(message)); } - sendGroup(); + for (auto &group : groups) { + const auto album = group.grouped + ? std::make_shared() + : nullptr; + session().api().sendFiles( + std::move(group.list), + type, + base::take(caption), + album, + action); + }; } bool HistoryWidget::confirmSendingFiles( @@ -4343,38 +4317,6 @@ bool HistoryWidget::confirmSendingFiles( return false; } -void HistoryWidget::uploadFilesAfterConfirmation( - Ui::PreparedList &&list, - SendMediaType type, - TextWithTags &&caption, - MsgId replyTo, - Api::SendOptions options, - std::shared_ptr album) { - Assert(canWriteMessage()); - - const auto isAlbum = (album != nullptr); - if (_peer->slowmodeApplied() - && ((list.files.size() > 1 && !album) - || (!list.files.empty() - && !caption.text.isEmpty() - && !list.canAddCaption(isAlbum)))) { - Ui::ShowMultilineToast({ - .text = { tr::lng_slowmode_no_many(tr::now) }, - }); - return; - } - - auto action = Api::SendAction(_history); - action.replyTo = replyTo; - action.options = options; - session().api().sendFiles( - std::move(list), - type, - std::move(caption), - album, - action); -} - void HistoryWidget::uploadFile( const QByteArray &fileContent, SendMediaType type) { diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 76b698785d..1a56edba19 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -434,15 +434,6 @@ private: bool ctrlShiftEnter); void uploadFile(const QByteArray &fileContent, SendMediaType type); - - void uploadFilesAfterConfirmation( - Ui::PreparedList &&list, - SendMediaType type, - TextWithTags &&caption, - MsgId replyTo, - Api::SendOptions options, - std::shared_ptr album = nullptr); - void itemRemoved(not_null item); // Updates position of controls around the message field, diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 46a0ed4f6b..7c534f7b91 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -621,25 +621,12 @@ bool RepliesWidget::confirmSendingFiles( TextWithTags &&caption, Api::SendOptions options, bool ctrlShiftEnter) { - if (showSendingFilesError(list)) { - return; - } - const auto type = way.sendImagesAsPhotos() - ? SendMediaType::Photo - : SendMediaType::File; - const auto album = way.groupMediaInAlbums() // #TODO files - ? std::make_shared() - : nullptr; - uploadFilesAfterConfirmation( + sendingFilesConfirmed( std::move(list), - type, + way, std::move(caption), - replyTo, options, - album); - if (_composeControls->replyingToMessage().msg == replyTo) { - _composeControls->cancelReplyMessage(); - } + ctrlShiftEnter); })); box->setCancelledCallback(crl::guard(this, [=] { _composeControls->setText(text); @@ -661,6 +648,51 @@ bool RepliesWidget::confirmSendingFiles( return true; } +void RepliesWidget::sendingFilesConfirmed( + Ui::PreparedList &&list, + Ui::SendFilesWay way, + TextWithTags &&caption, + Api::SendOptions options, + bool ctrlShiftEnter) { + Expects(list.filesToProcess.empty()); + + if (showSendingFilesError(list)) { + return; + } + auto groups = DivideByGroups( + std::move(list), + way, + _history->peer->slowmodeApplied()); + const auto replyTo = replyToId(); + const auto type = way.sendImagesAsPhotos() + ? SendMediaType::Photo + : SendMediaType::File; + auto action = Api::SendAction(_history); + action.replyTo = replyTo ? replyTo : _rootId; + action.options = options; + action.clearDraft = false; + if (groups.size() > 1 && !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 + ? std::make_shared() + : nullptr; + session().api().sendFiles( + std::move(group.list), + type, + base::take(caption), + album, + action); + }; + if (_composeControls->replyingToMessage().msg == replyTo) { + _composeControls->cancelReplyMessage(); + } +} + bool RepliesWidget::confirmSendingFiles( QImage &&image, QByteArray &&content, @@ -708,35 +740,6 @@ std::optional RepliesWidget::writeRestriction() const { ChatRestriction::f_send_messages); } -void RepliesWidget::uploadFilesAfterConfirmation( - Ui::PreparedList &&list, - SendMediaType type, - TextWithTags &&caption, - MsgId replyTo, - Api::SendOptions options, - std::shared_ptr album) { - const auto isAlbum = (album != nullptr); - if (_history->peer->slowmodeApplied() - && ((list.files.size() > 1 && !album) - || (!list.files.empty() - && !caption.text.isEmpty() - && !list.canAddCaption(isAlbum)))) { - Ui::ShowMultilineToast({ - .text = { tr::lng_slowmode_no_many(tr::now) } - }); - return; - } - auto action = Api::SendAction(_history); - action.replyTo = replyTo ? replyTo : _rootId; - action.options = options; - session().api().sendFiles( - std::move(list), - type, - std::move(caption), - album, - action); -} - void RepliesWidget::pushReplyReturn(not_null item) { if (item->history() == _history && item->replyToTop() == _rootId) { _replyReturns.push_back(item->id); diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.h b/Telegram/SourceFiles/history/view/history_view_replies_section.h index f7a6647408..cde6be8f29 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.h +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.h @@ -35,6 +35,7 @@ class FlatButton; class HistoryDownButton; class PinnedBar; struct PreparedList; +class SendFilesWay; } // namespace Ui namespace Profile { @@ -207,13 +208,12 @@ private: std::optional overrideSendImagesAsPhotos = std::nullopt, const QString &insertTextOnCancel = QString()); bool showSendingFilesError(const Ui::PreparedList &list) const; - void uploadFilesAfterConfirmation( + void sendingFilesConfirmed( Ui::PreparedList &&list, - SendMediaType type, + Ui::SendFilesWay way, TextWithTags &&caption, - MsgId replyTo, Api::SendOptions options, - std::shared_ptr album); + bool ctrlShiftEnter); void sendExistingDocument(not_null document); bool sendExistingDocument( diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index d16daf465f..8afba643f0 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -362,22 +362,12 @@ bool ScheduledWidget::confirmSendingFiles( TextWithTags &&caption, Api::SendOptions options, bool ctrlShiftEnter) { - if (showSendingFilesError(list)) { - return; - } - const auto type = way.sendImagesAsPhotos() - ? SendMediaType::Photo - : SendMediaType::File; - const auto album = way.groupMediaInAlbums() // #TODO files - ? std::make_shared() - : nullptr; - uploadFilesAfterConfirmation( + sendingFilesConfirmed( std::move(list), - type, + way, std::move(caption), - MsgId(0),//replyToId(), options, - album); + ctrlShiftEnter); })); //box->setCancelledCallback(crl::guard(this, [=] { // _field->setTextWithTags(text); @@ -399,6 +389,43 @@ bool ScheduledWidget::confirmSendingFiles( return true; } +void ScheduledWidget::sendingFilesConfirmed( + Ui::PreparedList &&list, + Ui::SendFilesWay way, + TextWithTags &&caption, + Api::SendOptions options, + bool ctrlShiftEnter) { + Expects(list.filesToProcess.empty()); + + if (showSendingFilesError(list)) { + return; + } + auto groups = DivideByGroups(std::move(list), way, false); + const auto type = way.sendImagesAsPhotos() + ? SendMediaType::Photo + : SendMediaType::File; + auto action = Api::SendAction(_history); + action.options = options; + action.clearDraft = false; + if (groups.size() > 1 && !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 + ? std::make_shared() + : nullptr; + session().api().sendFiles( + std::move(list), + type, + base::take(caption), + album, + action); + }; +} + bool ScheduledWidget::confirmSendingFiles( QImage &&image, QByteArray &&content, @@ -416,35 +443,6 @@ bool ScheduledWidget::confirmSendingFiles( return confirmSendingFiles(std::move(list), insertTextOnCancel); } -void ScheduledWidget::uploadFilesAfterConfirmation( - Ui::PreparedList &&list, - SendMediaType type, - TextWithTags &&caption, - MsgId replyTo, - Api::SendOptions options, - std::shared_ptr album) { - const auto isAlbum = (album != nullptr); - if (_history->peer->slowmodeApplied() - && ((list.files.size() > 1 && !album) - || (!list.files.empty() - && !caption.text.isEmpty() - && !list.canAddCaption(isAlbum)))) { - Ui::ShowMultilineToast({ - .text = { tr::lng_slowmode_no_many(tr::now) }, - }); - return; - } - auto action = Api::SendAction(_history); - action.replyTo = replyTo; - action.options = options; - session().api().sendFiles( - std::move(list), - type, - std::move(caption), - album, - action); -} - void ScheduledWidget::uploadFile( const QByteArray &fileContent, SendMediaType type) { diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h index 56c2377f46..ad7b55a565 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h @@ -30,6 +30,7 @@ class PlainShadow; class FlatButton; class HistoryDownButton; struct PreparedList; +class SendFilesWay; } // namespace Ui namespace Profile { @@ -173,13 +174,12 @@ private: std::optional overrideSendImagesAsPhotos = std::nullopt, const QString &insertTextOnCancel = QString()); bool showSendingFilesError(const Ui::PreparedList &list) const; - void uploadFilesAfterConfirmation( + void sendingFilesConfirmed( Ui::PreparedList &&list, - SendMediaType type, + Ui::SendFilesWay way, TextWithTags &&caption, - MsgId replyTo, Api::SendOptions options, - std::shared_ptr album); + bool ctrlShiftEnter); void sendExistingDocument(not_null document); bool sendExistingDocument( diff --git a/Telegram/SourceFiles/storage/details/storage_settings_scheme.cpp b/Telegram/SourceFiles/storage/details/storage_settings_scheme.cpp index 6550150a88..535deee66a 100644 --- a/Telegram/SourceFiles/storage/details/storage_settings_scheme.cpp +++ b/Telegram/SourceFiles/storage/details/storage_settings_scheme.cpp @@ -919,7 +919,7 @@ bool ReadSetting( if (!CheckStreamStatus(stream)) return false; auto way = Ui::SendFilesWay(); - way.setGroupMediaInAlbums(v == 1); + way.setGroupFiles(v == 1); way.setSendImagesAsPhotos(v == 1); Core::App().settings().setSendFilesWay(way); context.legacyRead = true; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp index fb67a6d15c..b90cd2609e 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp @@ -137,7 +137,7 @@ AlbumThumbnail *AlbumPreview::findThumb(QPoint position) const { ? st::sendMediaPreviewPhotoSkip : st::sendMediaFileThumbSkip; auto find = [&](const auto &thumb) { - if (_sendWay.groupMediaInAlbums()) { + if (_sendWay.groupFiles() && _sendWay.sendImagesAsPhotos()) { return thumb->containsPoint(position); } else { const auto bottom = top + (isPhotosWay @@ -258,13 +258,13 @@ void AlbumPreview::updateSizeAnimated( void AlbumPreview::updateSize() { const auto newHeight = [&] { - if (_sendWay.groupMediaInAlbums()) { - return int(std::round(_thumbsHeightAnimation.value( - _thumbsHeight))); - } else if (_sendWay.sendImagesAsPhotos()) { + if (!_sendWay.sendImagesAsPhotos()) { + return _filesHeight; + } else if (!_sendWay.groupFiles()) { return _photosHeight; } else { - return _filesHeight; + return int(std::round(_thumbsHeightAnimation.value( + _thumbsHeight))); } }(); if (height() != newHeight) { @@ -275,12 +275,12 @@ void AlbumPreview::updateSize() { void AlbumPreview::paintEvent(QPaintEvent *e) { Painter p(this); - if (_sendWay.groupMediaInAlbums()) { - paintAlbum(p); - } else if (_sendWay.sendImagesAsPhotos()) { + if (!_sendWay.sendImagesAsPhotos()) { + paintFiles(p, e->rect()); + } else if (!_sendWay.groupFiles()) { paintPhotos(p, e->rect()); } else { - paintFiles(p, e->rect()); + paintAlbum(p); } } @@ -409,7 +409,8 @@ void AlbumPreview::mouseMoveEvent(QMouseEvent *e) { applyCursor(style::cur_default); return; } - const auto isAlbum = _sendWay.groupMediaInAlbums(); + const auto isAlbum = _sendWay.sendImagesAsPhotos() + && _sendWay.groupFiles(); if (isAlbum && _draggedThumb) { const auto position = e->pos(); _draggedThumb->moveInAlbum(position - _draggedStartPosition); diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp index 33edeb0bad..d79be2777a 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "ui/chat/attach/attach_prepare.h" +#include "ui/chat/attach/attach_send_files_way.h" #include "core/mime_type.h" namespace Ui { @@ -21,7 +22,7 @@ PreparedFile::PreparedFile(const QString &path) : path(path) { PreparedFile::PreparedFile(PreparedFile &&other) = default; -PreparedFile &PreparedFile::operator=(PreparedFile && other) = default; +PreparedFile &PreparedFile::operator=(PreparedFile &&other) = default; PreparedFile::~PreparedFile() = default; @@ -90,7 +91,7 @@ bool PreparedList::canBeSentInSlowmodeWith(const PreparedList &other) const { return !hasNonGrouping && (!hasFiles || !hasVideos); } -bool PreparedList::canAddCaption(bool groupMediaInAlbums) const { +bool PreparedList::canAddCaption(bool sendingAlbum) const { if (!filesToProcess.empty() || files.empty() || files.size() > kMaxAlbumCount) { @@ -104,14 +105,18 @@ bool PreparedList::canAddCaption(bool groupMediaInAlbums) const { qstr(".tgs"), Qt::CaseInsensitive); return !isSticker; - } else if (!groupMediaInAlbums) { + } else if (!sendingAlbum) { return false; } const auto hasFiles = ranges::contains( files, PreparedFile::AlbumType::File, &PreparedFile::type); - return !hasFiles; + const auto hasNotGrouped = ranges::contains( + files, + PreparedFile::AlbumType::None, + &PreparedFile::type); + return !hasFiles && !hasNotGrouped; } int MaxAlbumItems() { @@ -125,4 +130,53 @@ bool ValidateThumbDimensions(int width, int height) { && (height < 20 * width); } +std::vector DivideByGroups( + PreparedList &&list, + SendFilesWay way, + bool slowmode) { + const auto sendImagesAsPhotos = way.sendImagesAsPhotos(); + const auto groupFiles = way.groupFiles() || slowmode; + + auto group = Ui::PreparedList(); + + // 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 result = std::vector(); + auto pushGroup = [&] { + result.push_back(PreparedGroup{ + .list = base::take(group), + .grouped = (groupType != Type::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) + : (file.type == Type::Photo) + ? ((groupFiles && sendImagesAsPhotos) + ? Type::Video + : (groupFiles && !sendImagesAsPhotos) + ? Type::File + : Type::None) + : (file.type == Type::File) + ? (groupFiles ? Type::File : Type::None) + : Type::None; + if ((!group.files.empty() && groupType != fileGroupType) + || ((groupType != Type::None) + && (group.files.size() == Ui::MaxAlbumItems()))) { + pushGroup(); + } + group.files.push_back(std::move(file)); + groupType = fileGroupType; + } + if (!group.files.empty()) { + pushGroup(); + } + return result; +} + } // namespace Ui diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h index 6e6419d9c3..b4f5bc4945 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h @@ -12,6 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { +class SendFilesWay; + struct PreparedFileInformation { struct Image { QImage data; @@ -37,11 +39,9 @@ struct PreparedFileInformation { struct PreparedFile { // File-s can be grouped if 'groupFiles'. // File-s + Photo-s can be grouped if 'groupFiles && !sendImagesAsPhotos'. - // Photo-s can be grouped if '(groupFiles && !sendImagesAsPhotos) - // || (groupMediaInAlbums && sendImagesAsPhotos)'. - // Photo-s + Video-s can be grouped if 'groupMediaInAlbums - // && sendImagesAsPhotos'. - // Video-s can be grouped if 'groupMediaInAlbums'. + // Photo-s can be grouped if 'groupFiles'. + // Photo-s + Video-s can be grouped if 'groupFiles && sendImagesAsPhotos'. + // Video-s can be grouped if 'groupFiles'. enum class AlbumType { File, Photo, @@ -77,12 +77,15 @@ struct PreparedList { : error(error) , errorData(errorData) { } + PreparedList(PreparedList &&other) = default; + PreparedList &operator=(PreparedList &&other) = default; + [[nodiscard]] static PreparedList Reordered( PreparedList &&list, std::vector order); void mergeToEnd(PreparedList &&other, bool cutToAlbumSize = false); - [[nodiscard]] bool canAddCaption(bool groupMediaInAlbums) const; + [[nodiscard]] bool canAddCaption(bool sendingAlbum) const; [[nodiscard]] bool canBeSentInSlowmode() const; [[nodiscard]] bool canBeSentInSlowmodeWith( const PreparedList &other) const; @@ -94,6 +97,16 @@ struct PreparedList { std::optional overrideSendImagesAsPhotos; }; +struct PreparedGroup { + PreparedList list; + bool grouped = false; +}; + +[[nodiscard]] std::vector DivideByGroups( + PreparedList &&list, + SendFilesWay way, + bool slowmode); + [[nodiscard]] int MaxAlbumItems(); [[nodiscard]] bool ValidateThumbDimensions(int width, int height); diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.cpp index 00fea6cd3e..159fe396ce 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.cpp @@ -9,19 +9,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { -void SendFilesWay::setGroupMediaInAlbums(bool value) { - if (value) { - _flags |= (Flag::GroupMediaInAlbums | Flag::SendImagesAsPhotos); - } else { - _flags &= ~Flag::GroupMediaInAlbums; - } -} - void SendFilesWay::setSendImagesAsPhotos(bool value) { if (value) { _flags |= Flag::SendImagesAsPhotos; } else { - _flags &= ~(Flag::SendImagesAsPhotos | Flag::GroupMediaInAlbums); + _flags &= ~Flag::SendImagesAsPhotos; } } @@ -40,36 +32,23 @@ void SendFilesWay::setGroupFiles(bool value) { //}; int32 SendFilesWay::serialize() const { - auto result = groupMediaInAlbums() + auto result = (sendImagesAsPhotos() && groupFiles()) ? int32(0) : sendImagesAsPhotos() ? int32(1) + : groupFiles() + ? int32(3) : int32(2); - if (!groupFiles()) { - result |= 0x04; - } return result; } std::optional SendFilesWay::FromSerialized(int32 value) { - auto result = SendFilesWay(); - result.setGroupFiles(!(value & 0x04)); - value &= ~0x04; - switch (value) { - case 0: - result.setGroupMediaInAlbums(true); - result.setSendImagesAsPhotos(true); - break; - case 1: - result.setGroupMediaInAlbums(false); - result.setSendImagesAsPhotos(true); - break; - case 2: - result.setGroupMediaInAlbums(false); - result.setSendImagesAsPhotos(false); - break; - default: return std::nullopt; + if (value < 0 || value > 3) { + return std::nullopt; } + auto result = SendFilesWay(); + result.setGroupFiles((value == 0) || (value == 3)); + result.setSendImagesAsPhotos((value == 0) || (value == 1)); return result; } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.h b/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.h index 53cb646c88..d155b14bfb 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.h @@ -19,18 +19,14 @@ enum class AttachButtonType { class SendFilesWay final { public: - [[nodiscard]] bool groupMediaInAlbums() const { - return (_flags & Flag::GroupMediaInAlbums) != 0; + [[nodiscard]] bool groupFiles() const { + return (_flags & Flag::GroupFiles) != 0; } [[nodiscard]] bool sendImagesAsPhotos() const { return (_flags & Flag::SendImagesAsPhotos) != 0; } - [[nodiscard]] bool groupFiles() const { - return (_flags & Flag::GroupFiles); - } - void setGroupMediaInAlbums(bool value); - void setSendImagesAsPhotos(bool value); void setGroupFiles(bool value); + void setSendImagesAsPhotos(bool value); [[nodiscard]] inline bool operator<(const SendFilesWay &other) const { return _flags < other._flags; @@ -57,11 +53,10 @@ public: private: enum class Flag : uchar { - GroupMediaInAlbums = (1 << 0), + GroupFiles = (1 << 0), SendImagesAsPhotos = (1 << 1), - GroupFiles = (1 << 2), - Default = GroupMediaInAlbums | SendImagesAsPhotos | GroupFiles, + Default = GroupFiles | SendImagesAsPhotos, }; friend inline constexpr bool is_flag_type(Flag) { return true; };