diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index f78d3dcd4..686d8924a 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -66,6 +66,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "chat_helpers/message_field.h" #include "ui/item_text_options.h" #include "ui/emoji_config.h" +#include "ui/chat/attach/attach_prepare.h" #include "support/support_helper.h" #include "storage/localimageloader.h" #include "storage/download_manager_mtproto.h" @@ -4183,7 +4184,7 @@ void ApiWrap::sendVoiceMessage( } void ApiWrap::editMedia( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendMediaType type, TextWithTags &&caption, const SendAction &action, @@ -4205,7 +4206,7 @@ void ApiWrap::editMedia( } void ApiWrap::sendFiles( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendMediaType type, TextWithTags &&caption, std::shared_ptr album, @@ -4231,10 +4232,10 @@ void ApiWrap::sendFiles( for (auto &file : list.files) { if (album) { switch (file.type) { - case Storage::PreparedFile::AlbumType::Photo: + case Ui::PreparedFile::AlbumType::Photo: type = SendMediaType::Photo; break; - case Storage::PreparedFile::AlbumType::Video: + case Ui::PreparedFile::AlbumType::Video: type = SendMediaType::File; break; default: Unexpected("AlbumType in uploadFilesAfterConfirmation"); diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index bf8140496..24c0d0960 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -36,7 +36,6 @@ class Result; namespace Storage { enum class SharedMediaType : signed char; -struct PreparedList; class DownloadMtprotoTask; class Account; } // namespace Storage @@ -49,6 +48,10 @@ namespace Core { struct CloudPasswordState; } // namespace Core +namespace Ui { +struct PreparedList; +} // namespace Ui + namespace Api { class Updates; @@ -393,7 +396,7 @@ public: int duration, const SendAction &action); void sendFiles( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendMediaType type, TextWithTags &&caption, std::shared_ptr album, @@ -404,7 +407,7 @@ public: const SendAction &action); void editMedia( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendMediaType type, TextWithTags &&caption, const SendAction &action, diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index 93ca21033..371d966f5 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -48,6 +48,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/checkbox.h" #include "ui/text/format_values.h" #include "ui/text/text_options.h" +#include "ui/chat/attach/attach_prepare.h" #include "ui/controls/emoji_button.h" #include "window/window_session_controller.h" #include "confirm_box.h" @@ -67,13 +68,13 @@ using namespace ::Media::Streaming; using Data::PhotoSize; auto ListFromMimeData(not_null data) { - using Error = Storage::PreparedList::Error; + using Error = Ui::PreparedList::Error; auto result = data->hasUrls() ? Storage::PrepareMediaList( // When we edit media, we need only 1 file. data->urls().mid(0, 1), st::sendMediaPreviewSize) - : Storage::PreparedList(Error::EmptyFile, QString()); + : Ui::PreparedList(Error::EmptyFile, QString()); if (result.error == Error::None) { return result; } else if (data->hasImage()) { @@ -475,7 +476,7 @@ void EditCaptionBox::streamingReady(Information &&info) { } void EditCaptionBox::updateEditPreview() { - using Info = FileMediaInformation; + using Info = Ui::PreparedFileInformation; const auto file = &_preparedList.files.front(); const auto fileMedia = &file->information->media; @@ -590,7 +591,7 @@ void EditCaptionBox::createEditMediaButton() { Ui::show(Box(t(tr::now)), Ui::LayerOption::KeepOther); }; - auto list = Storage::PreparedList::PreparedFileFromFilesDialog( + auto list = Storage::PreparedFileFromFilesDialog( std::move(result), _isAlbum, std::move(showBoxErrorCallback), @@ -677,8 +678,8 @@ bool EditCaptionBox::fileFromClipboard(not_null data) { if (!_isAllowedEditMedia) { return false; } - using Error = Storage::PreparedList::Error; - using AlbumType = Storage::PreparedFile::AlbumType; + using Error = Ui::PreparedList::Error; + using AlbumType = Ui::PreparedFile::AlbumType; auto list = ListFromMimeData(data); if (list.error != Error::None || list.files.empty()) { @@ -688,7 +689,7 @@ bool EditCaptionBox::fileFromClipboard(not_null data) { const auto file = &list.files.front(); if (_isAlbum && (file->type == AlbumType::None)) { const auto imageAsDoc = [&] { - using Info = FileMediaInformation; + using Info = Ui::PreparedFileInformation; const auto fileMedia = &file->information->media; if (const auto image = std::get_if(fileMedia)) { return !Storage::ValidateThumbDimensions( diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.h b/Telegram/SourceFiles/boxes/edit_caption_box.h index 4ffc10ffc..a91e35e9e 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.h +++ b/Telegram/SourceFiles/boxes/edit_caption_box.h @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/abstract_box.h" #include "storage/storage_media_prepare.h" #include "ui/wrap/slide_wrap.h" +#include "ui/chat/attach/attach_prepare.h" class Image; @@ -130,7 +131,7 @@ private: int _gifh = 0; int _gifx = 0; - Storage::PreparedList _preparedList; + Ui::PreparedList _preparedList; mtpRequestId _saveRequestId = 0; diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index a247b56b0..b927cc1f4 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/input_fields.h" #include "ui/widgets/scroll_area.h" #include "ui/wrap/fade_wrap.h" +#include "ui/chat/attach/attach_prepare.h" #include "ui/text/format_values.h" #include "ui/grouped_layout.h" #include "ui/text/text_options.h" @@ -67,13 +68,13 @@ inline bool CanAddUrls(const QList &urls) { return !urls.isEmpty() && ranges::all_of(urls, &QUrl::isLocalFile); } -inline bool IsFirstAlbumItem(const Storage::PreparedList &list) { - using AlbumType = Storage::PreparedFile::AlbumType; +inline bool IsFirstAlbumItem(const Ui::PreparedList &list) { + using AlbumType = Ui::PreparedFile::AlbumType; return (list.files.size() > 0) && (list.files.front().type != AlbumType::None); } -inline bool IsSingleItem(const Storage::PreparedList &list) { +inline bool IsSingleItem(const Ui::PreparedList &list) { return list.files.size() == 1; } @@ -132,12 +133,12 @@ QRect PaintAlbumThumbButtons( void FileDialogCallback( FileDialog::OpenResult &&result, bool isAlbum, - Fn callback) { + Fn callback) { auto showBoxErrorCallback = [](tr::phrase<> text) { Ui::show(Box(text(tr::now)), Ui::LayerOption::KeepOther); }; - auto list = Storage::PreparedList::PreparedFileFromFilesDialog( + auto list = Storage::PreparedFileFromFilesDialog( std::move(result), isAlbum, std::move(showBoxErrorCallback), @@ -155,7 +156,7 @@ public: static SingleMediaPreview *Create( QWidget *parent, not_null controller, - const Storage::PreparedFile &file); + const Ui::PreparedFile &file); SingleMediaPreview( QWidget *parent, @@ -198,7 +199,7 @@ class SingleFilePreview : public Ui::RpWidget { public: SingleFilePreview( QWidget *parent, - const Storage::PreparedFile &file); + const Ui::PreparedFile &file); rpl::producer desiredHeightValue() const override; @@ -206,7 +207,7 @@ protected: void paintEvent(QPaintEvent *e) override; private: - void preparePreview(const Storage::PreparedFile &file); + void preparePreview(const Ui::PreparedFile &file); void prepareThumb(const QImage &preview); QPixmap _fileThumb; @@ -221,7 +222,7 @@ private: class AlbumThumb { public: AlbumThumb( - const Storage::PreparedFile &file, + const Ui::PreparedFile &file, const Ui::GroupMediaLayout &layout, QWidget *parent, Fn editCallback, @@ -287,7 +288,7 @@ private: }; AlbumThumb::AlbumThumb( - const Storage::PreparedFile &file, + const Ui::PreparedFile &file, const Ui::GroupMediaLayout &layout, QWidget *parent, Fn editCallback, @@ -295,7 +296,7 @@ AlbumThumb::AlbumThumb( : _layout(layout) , _fullPreview(file.preview) , _shrinkSize(int(std::ceil(st::historyMessageRadius / 1.4))) -, _isVideo(file.type == Storage::PreparedFile::AlbumType::Video) { +, _isVideo(file.type == Ui::PreparedFile::AlbumType::Video) { Expects(!_fullPreview.isNull()); moveToLayout(layout); @@ -762,15 +763,15 @@ void AlbumThumb::finishAnimations() { SingleMediaPreview *SingleMediaPreview::Create( QWidget *parent, not_null controller, - const Storage::PreparedFile &file) { + const Ui::PreparedFile &file) { auto preview = QImage(); bool animated = false; bool animationPreview = false; - if (const auto image = std::get_if( + if (const auto image = std::get_if( &file.information->media)) { preview = image->data; animated = animationPreview = image->animated; - } else if (const auto video = std::get_if( + } else if (const auto video = std::get_if( &file.information->media)) { preview = video->thumbnail; animated = true; @@ -970,7 +971,7 @@ rpl::producer SingleMediaPreview::desiredHeightValue() const { SingleFilePreview::SingleFilePreview( QWidget *parent, - const Storage::PreparedFile &file) + const Ui::PreparedFile &file) : RpWidget(parent) { preparePreview(file); } @@ -1002,12 +1003,12 @@ void SingleFilePreview::prepareThumb(const QImage &preview) { st::msgFileThumbSize)); } -void SingleFilePreview::preparePreview(const Storage::PreparedFile &file) { +void SingleFilePreview::preparePreview(const Ui::PreparedFile &file) { auto preview = QImage(); - if (const auto image = std::get_if( + if (const auto image = std::get_if( &file.information->media)) { preview = image->data; - } else if (const auto video = std::get_if( + } else if (const auto video = std::get_if( &file.information->media)) { preview = video->thumbnail; } @@ -1034,7 +1035,7 @@ void SingleFilePreview::preparePreview(const Storage::PreparedFile &file) { auto songTitle = QString(); auto songPerformer = QString(); if (file.information) { - if (const auto song = std::get_if( + if (const auto song = std::get_if( &file.information->media)) { songTitle = song->title; songPerformer = song->performer; @@ -1118,7 +1119,7 @@ rpl::producer SingleFilePreview::desiredHeightValue() const { } rpl::producer FieldPlaceholder( - const Storage::PreparedList &list, + const Ui::PreparedList &list, SendFilesWay way) { const auto isAlbum = (way == SendFilesWay::Album); const auto compressImages = (way != SendFilesWay::Files); @@ -1133,7 +1134,7 @@ class SendFilesBox::AlbumPreview : public Ui::RpWidget { public: AlbumPreview( QWidget *parent, - const Storage::PreparedList &list, + const Ui::PreparedList &list, SendFilesWay way); void setSendWay(SendFilesWay way); @@ -1185,7 +1186,7 @@ private: void cancelDrag(); void finishDrag(); - const Storage::PreparedList &_list; + const Ui::PreparedList &_list; SendFilesWay _sendWay = SendFilesWay::Files; style::cursor _cursor = style::cur_default; std::vector _order; @@ -1210,7 +1211,7 @@ private: SendFilesBox::AlbumPreview::AlbumPreview( QWidget *parent, - const Storage::PreparedList &list, + const Ui::PreparedList &list, SendFilesWay way) : RpWidget(parent) , _list(list) @@ -1662,7 +1663,7 @@ void SendFilesBox::AlbumPreview::mouseReleaseEvent(QMouseEvent *e) { SendFilesBox::SendFilesBox( QWidget*, not_null controller, - Storage::PreparedList &&list, + Ui::PreparedList &&list, const TextWithTags &caption, CompressConfirm compressed, SendLimit limit, @@ -1899,7 +1900,7 @@ void SendFilesBox::setupDragArea() { void SendFilesBox::updateLeftButtonVisibility() { const auto isAlbum = _list.albumIsPossible - && (_list.files.size() < Storage::MaxAlbumItems()); + && (_list.files.size() < Ui::MaxAlbumItems()); if (isAlbum || (IsSingleItem(_list) && IsFirstAlbumItem(_list))) { _addFileToAlbum->show(); } else { @@ -1999,8 +2000,8 @@ void SendFilesBox::refreshAlbumMediaCount() { _albumVideosCount = _list.albumIsPossible ? ranges::count( _list.files, - Storage::PreparedFile::AlbumType::Video, - [](const Storage::PreparedFile &file) { return file.type; }) + Ui::PreparedFile::AlbumType::Video, + [](const Ui::PreparedFile &file) { return file.type; }) : 0; _albumPhotosCount = _list.albumIsPossible ? (_list.files.size() - _albumVideosCount) @@ -2076,7 +2077,7 @@ void SendFilesBox::applyAlbumOrder() { return; } - _list = Storage::PreparedList::Reordered(std::move(_list), order); + _list = Ui::PreparedList::Reordered(std::move(_list), order); } void SendFilesBox::setupCaption() { @@ -2189,7 +2190,7 @@ bool SendFilesBox::canAddFiles(not_null data) const { ++filesCount; } - if (_list.files.size() + filesCount > Storage::MaxAlbumItems()) { + if (_list.files.size() + filesCount > Ui::MaxAlbumItems()) { return false; } else if (_list.files.size() > 1 && !_albumPreview) { return false; @@ -2204,10 +2205,10 @@ bool SendFilesBox::addFiles(not_null data) { const auto urls = data->hasUrls() ? data->urls() : QList(); auto result = CanAddUrls(urls) ? Storage::PrepareMediaList(urls, st::sendMediaPreviewSize) - : Storage::PreparedList( - Storage::PreparedList::Error::EmptyFile, + : Ui::PreparedList( + Ui::PreparedList::Error::EmptyFile, QString()); - if (result.error == Storage::PreparedList::Error::None) { + if (result.error == Ui::PreparedList::Error::None) { return result; } else if (data->hasImage()) { auto image = Platform::GetImageFromClipboard(); @@ -2226,10 +2227,10 @@ bool SendFilesBox::addFiles(not_null data) { return addFiles(std::move(list)); } -bool SendFilesBox::addFiles(Storage::PreparedList list) { +bool SendFilesBox::addFiles(Ui::PreparedList list) { const auto sumFiles = _list.files.size() + list.files.size(); - const auto cutToAlbumSize = (sumFiles > Storage::MaxAlbumItems()); - if (list.error != Storage::PreparedList::Error::None) { + const auto cutToAlbumSize = (sumFiles > Ui::MaxAlbumItems()); + if (list.error != Ui::PreparedList::Error::None) { return false; } else if (!IsSingleItem(list) && !list.albumIsPossible) { return false; diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index e7b013071..d8bfc5f99 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include "boxes/abstract_box.h" +#include "ui/chat/attach/attach_prepare.h" #include "storage/localimageloader.h" #include "storage/storage_media_prepare.h" @@ -59,7 +60,7 @@ public: SendFilesBox( QWidget*, not_null controller, - Storage::PreparedList &&list, + Ui::PreparedList &&list, const TextWithTags &caption, CompressConfirm compressed, SendLimit limit, @@ -68,7 +69,7 @@ public: void setConfirmedCallback( Fn data) const; bool addFiles(not_null data); - bool addFiles(Storage::PreparedList list); + bool addFiles(Ui::PreparedList list); void openDialogToAddFileToAlbum(); void updateLeftButtonVisibility(); @@ -139,7 +140,7 @@ private: QString _titleText; int _titleHeight = 0; - Storage::PreparedList _list; + Ui::PreparedList _list; CompressConfirm _compressConfirmInitial = CompressConfirm::None; CompressConfirm _compressConfirm = CompressConfirm::None; @@ -147,7 +148,7 @@ private: SendMenu::Type _sendMenuType = SendMenu::Type(); Fn #include #include #include diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 751f3023b..9abb0d823 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/toasts/common_toasts.h" #include "ui/special_buttons.h" #include "ui/emoji_config.h" +#include "ui/chat/attach/attach_prepare.h" #include "ui/widgets/buttons.h" #include "ui/widgets/inner_dropdown.h" #include "ui/widgets/dropdown_menu.h" @@ -4091,7 +4092,7 @@ void HistoryWidget::updateFieldPlaceholder() { } bool HistoryWidget::showSendingFilesError( - const Storage::PreparedList &list) const { + const Ui::PreparedList &list) const { const auto text = [&] { const auto error = _peer ? Data::RestrictionError( @@ -4113,7 +4114,7 @@ bool HistoryWidget::showSendingFilesError( lt_left, Ui::FormatDurationWords(left)); } - using Error = Storage::PreparedList::Error; + using Error = Ui::PreparedList::Error; switch (list.error) { case Error::None: return QString(); case Error::EmptyFile: @@ -4158,7 +4159,7 @@ bool HistoryWidget::confirmSendingFiles( } bool HistoryWidget::confirmSendingFiles( - Storage::PreparedList &&list, + Ui::PreparedList &&list, CompressConfirm compressed, const QString &insertTextOnCancel) { if (showSendingFilesError(list)) { @@ -4191,7 +4192,7 @@ bool HistoryWidget::confirmSendingFiles( sendMenuType()); _field->setTextWithTags({}); box->setConfirmedCallback(crl::guard(this, [=]( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendFilesWay way, TextWithTags &&caption, Api::SendOptions options, @@ -4279,8 +4280,8 @@ bool HistoryWidget::confirmSendingFiles( auto list = Storage::PrepareMediaList( urls, st::sendMediaPreviewSize); - if (list.error != Storage::PreparedList::Error::NonLocalUrl) { - if (list.error == Storage::PreparedList::Error::None + if (list.error != Ui::PreparedList::Error::NonLocalUrl) { + if (list.error == Ui::PreparedList::Error::None || !hasImage) { const auto emptyTextOnCancel = QString(); confirmSendingFiles( @@ -4310,7 +4311,7 @@ bool HistoryWidget::confirmSendingFiles( } void HistoryWidget::uploadFilesAfterConfirmation( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendMediaType type, TextWithTags &&caption, MsgId replyTo, diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 230570317..2e5f034c8 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -21,7 +21,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class RPCError; struct FileLoadResult; -struct FileMediaInformation; struct SendingAlbum; enum class SendMediaType; enum class CompressConfirm; @@ -67,6 +66,7 @@ class FlatButton; class LinkButton; class RoundButton; class PinnedBar; +struct PreparedList; namespace Toast { class Instance; } // namespace Toast @@ -84,7 +84,6 @@ class TabbedSelector; namespace Storage { enum class MimeDataState; -struct PreparedList; struct UploadedPhoto; struct UploadedDocument; struct UploadedThumbDocument; @@ -424,15 +423,15 @@ private: CompressConfirm compressed, const QString &insertTextOnCancel = QString()); bool confirmSendingFiles( - Storage::PreparedList &&list, + Ui::PreparedList &&list, CompressConfirm compressed, const QString &insertTextOnCancel = QString()); - bool showSendingFilesError(const Storage::PreparedList &list) const; + bool showSendingFilesError(const Ui::PreparedList &list) const; void uploadFile(const QByteArray &fileContent, SendMediaType type); void uploadFilesAfterConfirmation( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendMediaType type, TextWithTags &&caption, MsgId replyTo, diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 41d644c40..613acdc9d 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/toast/toast.h" #include "ui/text/format_values.h" #include "ui/text/text_utilities.h" +#include "ui/chat/attach/attach_prepare.h" #include "ui/special_buttons.h" #include "ui/ui_utility.h" #include "ui/toasts/common_toasts.h" @@ -571,8 +572,8 @@ bool RepliesWidget::confirmSendingFiles( auto list = Storage::PrepareMediaList( urls, st::sendMediaPreviewSize); - if (list.error != Storage::PreparedList::Error::NonLocalUrl) { - if (list.error == Storage::PreparedList::Error::None + if (list.error != Ui::PreparedList::Error::NonLocalUrl) { + if (list.error == Ui::PreparedList::Error::None || !hasImage) { const auto emptyTextOnCancel = QString(); confirmSendingFiles( @@ -602,7 +603,7 @@ bool RepliesWidget::confirmSendingFiles( } bool RepliesWidget::confirmSendingFiles( - Storage::PreparedList &&list, + Ui::PreparedList &&list, CompressConfirm compressed, const QString &insertTextOnCancel) { if (showSendingFilesError(list)) { @@ -633,7 +634,7 @@ bool RepliesWidget::confirmSendingFiles( const auto replyTo = replyToId(); box->setConfirmedCallback(crl::guard(this, [=]( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendFilesWay way, TextWithTags &&caption, Api::SendOptions options, @@ -728,7 +729,7 @@ std::optional RepliesWidget::writeRestriction() const { } void RepliesWidget::uploadFilesAfterConfirmation( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendMediaType type, TextWithTags &&caption, MsgId replyTo, @@ -818,7 +819,7 @@ void RepliesWidget::uploadFile( } bool RepliesWidget::showSendingFilesError( - const Storage::PreparedList &list) const { + const Ui::PreparedList &list) const { const auto text = [&] { const auto error = Data::RestrictionError( _history->peer, @@ -836,7 +837,7 @@ bool RepliesWidget::showSendingFilesError( lt_left, Ui::FormatDurationWords(left)); } - using Error = Storage::PreparedList::Error; + using Error = Ui::PreparedList::Error; switch (list.error) { case Error::None: return QString(); case Error::EmptyFile: diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.h b/Telegram/SourceFiles/history/view/history_view_replies_section.h index 5adf27731..97e061a55 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.h +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.h @@ -27,7 +27,6 @@ struct SendOptions; } // namespace Api namespace Storage { -struct PreparedList; } // namespace Storage namespace Ui { @@ -36,6 +35,7 @@ class PlainShadow; class FlatButton; class HistoryDownButton; class PinnedBar; +struct PreparedList; } // namespace Ui namespace Profile { @@ -201,16 +201,16 @@ private: CompressConfirm compressed, const QString &insertTextOnCancel = QString()); bool confirmSendingFiles( - Storage::PreparedList &&list, + Ui::PreparedList &&list, CompressConfirm compressed, const QString &insertTextOnCancel = QString()); bool confirmSendingFiles( not_null data, CompressConfirm compressed, const QString &insertTextOnCancel = QString()); - bool showSendingFilesError(const Storage::PreparedList &list) const; + bool showSendingFilesError(const Ui::PreparedList &list) const; void uploadFilesAfterConfirmation( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendMediaType type, TextWithTags &&caption, MsgId replyTo, diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index dca932b12..ad47b2da3 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/layers/generic_box.h" #include "ui/item_text_options.h" #include "ui/toast/toast.h" +#include "ui/chat/attach/attach_prepare.h" #include "ui/special_buttons.h" #include "ui/ui_utility.h" #include "ui/toasts/common_toasts.h" @@ -311,8 +312,8 @@ bool ScheduledWidget::confirmSendingFiles( auto list = Storage::PrepareMediaList( urls, st::sendMediaPreviewSize); - if (list.error != Storage::PreparedList::Error::NonLocalUrl) { - if (list.error == Storage::PreparedList::Error::None + if (list.error != Ui::PreparedList::Error::NonLocalUrl) { + if (list.error == Ui::PreparedList::Error::None || !hasImage) { const auto emptyTextOnCancel = QString(); confirmSendingFiles( @@ -342,7 +343,7 @@ bool ScheduledWidget::confirmSendingFiles( } bool ScheduledWidget::confirmSendingFiles( - Storage::PreparedList &&list, + Ui::PreparedList &&list, CompressConfirm compressed, const QString &insertTextOnCancel) { if (showSendingFilesError(list)) { @@ -374,7 +375,7 @@ bool ScheduledWidget::confirmSendingFiles( //_field->setTextWithTags({}); box->setConfirmedCallback(crl::guard(this, [=]( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendFilesWay way, TextWithTags &&caption, Api::SendOptions options, @@ -436,7 +437,7 @@ bool ScheduledWidget::confirmSendingFiles( } void ScheduledWidget::uploadFilesAfterConfirmation( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendMediaType type, TextWithTags &&caption, MsgId replyTo, @@ -480,7 +481,7 @@ void ScheduledWidget::uploadFile( } bool ScheduledWidget::showSendingFilesError( - const Storage::PreparedList &list) const { + const Ui::PreparedList &list) const { const auto text = [&] { const auto error = Data::RestrictionError( _history->peer, @@ -488,7 +489,7 @@ bool ScheduledWidget::showSendingFilesError( if (error) { return *error; } - using Error = Storage::PreparedList::Error; + using Error = Ui::PreparedList::Error; switch (list.error) { case Error::None: return QString(); case Error::EmptyFile: diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h index 1cc916625..57af2c5c3 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h @@ -25,15 +25,12 @@ namespace Api { struct SendOptions; } // namespace Api -namespace Storage { -struct PreparedList; -} // namespace Storage - namespace Ui { class ScrollArea; class PlainShadow; class FlatButton; class HistoryDownButton; +struct PreparedList; } // namespace Ui namespace Profile { @@ -170,16 +167,16 @@ private: CompressConfirm compressed, const QString &insertTextOnCancel = QString()); bool confirmSendingFiles( - Storage::PreparedList &&list, + Ui::PreparedList &&list, CompressConfirm compressed, const QString &insertTextOnCancel = QString()); bool confirmSendingFiles( not_null data, CompressConfirm compressed, const QString &insertTextOnCancel = QString()); - bool showSendingFilesError(const Storage::PreparedList &list) const; + bool showSendingFilesError(const Ui::PreparedList &list) const; void uploadFilesAfterConfirmation( - Storage::PreparedList &&list, + Ui::PreparedList &&list, SendMediaType type, TextWithTags &&caption, MsgId replyTo, diff --git a/Telegram/SourceFiles/media/audio/media_audio.cpp b/Telegram/SourceFiles/media/audio/media_audio.cpp index 5e79687ad..e429ee774 100644 --- a/Telegram/SourceFiles/media/audio/media_audio.cpp +++ b/Telegram/SourceFiles/media/audio/media_audio.cpp @@ -1630,8 +1630,8 @@ private: namespace Player { -FileMediaInformation::Song PrepareForSending(const QString &fname, const QByteArray &data) { - auto result = FileMediaInformation::Song(); +Ui::PreparedFileInformation::Song PrepareForSending(const QString &fname, const QByteArray &data) { + auto result = Ui::PreparedFileInformation::Song(); FFMpegAttributesReader reader(FileLocation(fname), data); const auto positionMs = crl::time(0); if (reader.open(positionMs) && reader.samplesCount() > 0) { diff --git a/Telegram/SourceFiles/media/audio/media_audio.h b/Telegram/SourceFiles/media/audio/media_audio.h index 369ee4507..962017073 100644 --- a/Telegram/SourceFiles/media/audio/media_audio.h +++ b/Telegram/SourceFiles/media/audio/media_audio.h @@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "ui/effects/animation_value.h" -#include "storage/localimageloader.h" +#include "ui/chat/attach/attach_prepare.h" #include "base/bytes.h" #include @@ -345,7 +345,9 @@ private: }; -FileMediaInformation::Song PrepareForSending(const QString &fname, const QByteArray &data); +[[nodiscard]] Ui::PreparedFileInformation::Song PrepareForSending( + const QString &fname, + const QByteArray &data); namespace internal { diff --git a/Telegram/SourceFiles/media/clip/media_clip_reader.cpp b/Telegram/SourceFiles/media/clip/media_clip_reader.cpp index 84b57b9a6..7cb071529 100644 --- a/Telegram/SourceFiles/media/clip/media_clip_reader.cpp +++ b/Telegram/SourceFiles/media/clip/media_clip_reader.cpp @@ -883,8 +883,8 @@ Manager::~Manager() { clear(); } -FileMediaInformation::Video PrepareForSending(const QString &fname, const QByteArray &data) { - auto result = FileMediaInformation::Video(); +Ui::PreparedFileInformation::Video PrepareForSending(const QString &fname, const QByteArray &data) { + auto result = Ui::PreparedFileInformation::Video(); auto localLocation = FileLocation(fname); auto localData = QByteArray(data); diff --git a/Telegram/SourceFiles/media/clip/media_clip_reader.h b/Telegram/SourceFiles/media/clip/media_clip_reader.h index fc85b1e10..cb84dffd9 100644 --- a/Telegram/SourceFiles/media/clip/media_clip_reader.h +++ b/Telegram/SourceFiles/media/clip/media_clip_reader.h @@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "storage/localimageloader.h" +#include "ui/chat/attach/attach_prepare.h" #include "ui/image/image_prepare.h" #include @@ -294,7 +294,9 @@ private: }; -FileMediaInformation::Video PrepareForSending(const QString &fname, const QByteArray &data); +[[nodiscard]] Ui::PreparedFileInformation::Video PrepareForSending( + const QString &fname, + const QByteArray &data); void Finish(); diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp index 09f7146ac..782e73fb3 100644 --- a/Telegram/SourceFiles/storage/localimageloader.cpp +++ b/Telegram/SourceFiles/storage/localimageloader.cpp @@ -489,7 +489,7 @@ FileLoadTask::FileLoadTask( not_null session, const QString &filepath, const QByteArray &content, - std::unique_ptr information, + std::unique_ptr information, SendMediaType type, const FileLoadTo &to, const TextWithTags &caption, @@ -528,11 +528,13 @@ FileLoadTask::FileLoadTask( , _caption(caption) { } -std::unique_ptr FileLoadTask::ReadMediaInformation( +FileLoadTask::~FileLoadTask() = default; + +std::unique_ptr FileLoadTask::ReadMediaInformation( const QString &filepath, const QByteArray &content, const QString &filemime) { - auto result = std::make_unique(); + auto result = std::make_unique(); result->filemime = filemime; if (CheckForSong(filepath, content, result)) { @@ -565,7 +567,7 @@ bool FileLoadTask::CheckMimeOrExtensions( bool FileLoadTask::CheckForSong( const QString &filepath, const QByteArray &content, - std::unique_ptr &result) { + std::unique_ptr &result) { static const auto mimes = { qstr("audio/mp3"), qstr("audio/m4a"), @@ -606,7 +608,7 @@ bool FileLoadTask::CheckForSong( bool FileLoadTask::CheckForVideo( const QString &filepath, const QByteArray &content, - std::unique_ptr &result) { + std::unique_ptr &result) { static const auto mimes = { qstr("video/mp4"), qstr("video/quicktime"), @@ -640,7 +642,7 @@ bool FileLoadTask::CheckForVideo( bool FileLoadTask::CheckForImage( const QString &filepath, const QByteArray &content, - std::unique_ptr &result) { + std::unique_ptr &result) { auto animated = false; auto image = [&] { if (filepath.endsWith(qstr(".tgs"), Qt::CaseInsensitive)) { @@ -665,13 +667,13 @@ bool FileLoadTask::CheckForImage( bool FileLoadTask::FillImageInformation( QImage &&image, bool animated, - std::unique_ptr &result) { + std::unique_ptr &result) { Expects(result != nullptr); if (image.isNull()) { return false; } - auto media = FileMediaInformation::Image(); + auto media = Ui::PreparedFileInformation::Image(); media.data = std::move(image); media.animated = animated; result->media = media; @@ -717,7 +719,7 @@ void FileLoadTask::process() { _information = readMediaInformation(Core::MimeTypeForFile(info).name()); } filemime = _information->filemime; - if (auto image = std::get_if( + if (auto image = std::get_if( &_information->media)) { fullimage = base::take(image->data); if (!Core::IsMimeSticker(filemime)) { @@ -732,7 +734,7 @@ void FileLoadTask::process() { filemime = "audio/ogg"; } else { if (_information) { - if (auto image = std::get_if( + if (auto image = std::get_if( &_information->media)) { fullimage = base::take(image->data); } @@ -757,7 +759,7 @@ void FileLoadTask::process() { } } else { if (_information) { - if (auto image = std::get_if( + if (auto image = std::get_if( &_information->media)) { fullimage = base::take(image->data); } @@ -807,13 +809,13 @@ void FileLoadTask::process() { _information = readMediaInformation(filemime); filemime = _information->filemime; } - if (auto song = std::get_if( + if (auto song = std::get_if( &_information->media)) { isSong = true; auto flags = MTPDdocumentAttributeAudio::Flag::f_title | MTPDdocumentAttributeAudio::Flag::f_performer; attributes.push_back(MTP_documentAttributeAudio(MTP_flags(flags), MTP_int(song->duration), MTP_string(song->title), MTP_string(song->performer), MTPstring())); thumbnail = PrepareFileThumbnail(std::move(song->cover)); - } else if (auto video = std::get_if( + } else if (auto video = std::get_if( &_information->media)) { isVideo = true; auto coverWidth = video->thumbnail.width(); @@ -996,6 +998,11 @@ FileLoadResult *FileLoadTask::peekResult() const { return _result.get(); } +std::unique_ptr FileLoadTask::readMediaInformation( + const QString &filemime) const { + return ReadMediaInformation(_filepath, _content, filemime); +} + void FileLoadTask::removeFromAlbum() { if (!_album) { return; diff --git a/Telegram/SourceFiles/storage/localimageloader.h b/Telegram/SourceFiles/storage/localimageloader.h index fed9e2a9d..e80058430 100644 --- a/Telegram/SourceFiles/storage/localimageloader.h +++ b/Telegram/SourceFiles/storage/localimageloader.h @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/variant.h" #include "api/api_common.h" +#include "ui/chat/attach/attach_prepare.h" constexpr auto kFileSizeLimit = 2000 * 1024 * 1024; // Load files up to 1500mb @@ -239,44 +240,22 @@ struct FileLoadResult { }; -struct FileMediaInformation { - struct Image { - QImage data; - bool animated = false; - }; - struct Song { - int duration = -1; - QString title; - QString performer; - QImage cover; - }; - struct Video { - bool isGifv = false; - bool supportsStreaming = false; - int duration = -1; - QImage thumbnail; - }; - - QString filemime; - std::variant media; -}; - class FileLoadTask final : public Task { public: - static std::unique_ptr ReadMediaInformation( + static std::unique_ptr ReadMediaInformation( const QString &filepath, const QByteArray &content, const QString &filemime); static bool FillImageInformation( QImage &&image, bool animated, - std::unique_ptr &result); + std::unique_ptr &result); FileLoadTask( not_null session, const QString &filepath, const QByteArray &content, - std::unique_ptr information, + std::unique_ptr information, SendMediaType type, const FileLoadTo &to, const TextWithTags &caption, @@ -289,6 +268,7 @@ public: const VoiceWaveform &waveform, const FileLoadTo &to, const TextWithTags &caption); + ~FileLoadTask(); uint64 fileid() const { return _id; @@ -303,22 +283,20 @@ private: static bool CheckForSong( const QString &filepath, const QByteArray &content, - std::unique_ptr &result); + std::unique_ptr &result); static bool CheckForVideo( const QString &filepath, const QByteArray &content, - std::unique_ptr &result); + std::unique_ptr &result); static bool CheckForImage( const QString &filepath, const QByteArray &content, - std::unique_ptr &result); + std::unique_ptr &result); template static bool CheckMimeOrExtensions(const QString &filepath, const QString &filemime, Mimes &mimes, Extensions &extensions); - std::unique_ptr readMediaInformation(const QString &filemime) const { - return ReadMediaInformation(_filepath, _content, filemime); - } + std::unique_ptr readMediaInformation(const QString &filemime) const; void removeFromAlbum(); uint64 _id = 0; @@ -328,7 +306,7 @@ private: const std::shared_ptr _album; QString _filepath; QByteArray _content; - std::unique_ptr _information; + std::unique_ptr _information; int32 _duration = 0; VoiceWaveform _waveform; SendMediaType _type; diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.cpp b/Telegram/SourceFiles/storage/storage_media_prepare.cpp index 6099d31df..629ea4766 100644 --- a/Telegram/SourceFiles/storage/storage_media_prepare.cpp +++ b/Telegram/SourceFiles/storage/storage_media_prepare.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/mime_type.h" #include "ui/image/image_prepare.h" #include "ui/chat/attach/attach_extensions.h" +#include "ui/chat/attach/attach_prepare.h" #include "app.h" #include @@ -20,7 +21,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Storage { namespace { -constexpr auto kMaxAlbumCount = 10; +using Ui::PreparedFileInformation; +using Ui::PreparedFile; +using Ui::PreparedList; bool HasExtensionFrom(const QString &file, const QStringList &extensions) { for (const auto &extension : extensions) { @@ -33,7 +36,7 @@ bool HasExtensionFrom(const QString &file, const QStringList &extensions) { } bool ValidPhotoForAlbum( - const FileMediaInformation::Image &image, + const PreparedFileInformation::Image &image, const QString &mime) { if (image.animated || Core::IsMimeSticker(mime)) { return false; @@ -43,7 +46,7 @@ bool ValidPhotoForAlbum( return ValidateThumbDimensions(width, height); } -bool ValidVideoForAlbum(const FileMediaInformation::Video &video) { +bool ValidVideoForAlbum(const PreparedFileInformation::Video &video) { const auto width = video.thumbnail.width(); const auto height = video.thumbnail.height(); return ValidateThumbDimensions(width, height); @@ -82,8 +85,8 @@ bool PrepareAlbumMediaIsWaiting( Assert(file.information != nullptr); } - using Image = FileMediaInformation::Image; - using Video = FileMediaInformation::Video; + using Image = PreparedFileInformation::Image; + using Video = PreparedFileInformation::Video; if (const auto image = std::get_if( &file.information->media)) { if (ValidPhotoForAlbum(*image, file.mime)) { @@ -115,7 +118,7 @@ bool PrepareAlbumMediaIsWaiting( void PrepareAlbum(PreparedList &result, int previewWidth) { const auto count = int(result.files.size()); - if (count > kMaxAlbumCount) { + if (count > Ui::MaxAlbumItems()) { return; } @@ -167,15 +170,6 @@ bool ValidateThumbDimensions(int width, int height) { && (height < 20 * width); } -PreparedFile::PreparedFile(const QString &path) : path(path) { -} - -PreparedFile::PreparedFile(PreparedFile &&other) = default; - -PreparedFile &PreparedFile::operator=(PreparedFile &&other) = default; - -PreparedFile::~PreparedFile() = default; - MimeDataState ComputeMimeDataState(const QMimeData *data) { if (!data || data->hasFormat(qsl("application/x-td-forward"))) { return MimeDataState::None; @@ -284,7 +278,7 @@ PreparedList PrepareMediaFromImage( auto file = PreparedFile(QString()); file.content = content; if (file.content.isEmpty()) { - file.information = std::make_unique(); + file.information = std::make_unique(); const auto animated = false; FileLoadTask::FillImageInformation( std::move(image), @@ -296,7 +290,7 @@ PreparedList PrepareMediaFromImage( return result; } -std::optional PreparedList::PreparedFileFromFilesDialog( +std::optional PreparedFileFromFilesDialog( FileDialog::OpenResult &&result, bool isAlbum, Fn)> errorCallback, @@ -347,7 +341,7 @@ std::optional PreparedList::PreparedFileFromFilesDialog( if (!isAlbum) { return true; } - using Info = FileMediaInformation; + using Info = PreparedFileInformation; const auto media = &file.information->media; const auto valid = v::match(*media, [](const Info::Image &data) { @@ -386,68 +380,5 @@ std::optional PreparedList::PreparedFileFromFilesDialog( return std::nullopt; } -PreparedList PreparedList::Reordered( - PreparedList &&list, - std::vector order) { - Expects(list.error == PreparedList::Error::None); - Expects(list.files.size() == order.size()); - - auto result = PreparedList(list.error, list.errorData); - result.albumIsPossible = list.albumIsPossible; - result.allFilesForCompress = list.allFilesForCompress; - result.files.reserve(list.files.size()); - for (auto index : order) { - result.files.push_back(std::move(list.files[index])); - } - return result; -} - -void PreparedList::mergeToEnd(PreparedList &&other, bool cutToAlbumSize) { - if (error != Error::None) { - return; - } - if (other.error != Error::None) { - error = other.error; - errorData = other.errorData; - return; - } - allFilesForCompress = allFilesForCompress && other.allFilesForCompress; - files.reserve(std::min( - size_t(cutToAlbumSize ? kMaxAlbumCount : INT_MAX), - files.size() + other.files.size())); - for (auto &file : other.files) { - if (cutToAlbumSize && files.size() == kMaxAlbumCount) { - break; - } - files.push_back(std::move(file)); - } - if (files.size() > 1 && files.size() <= kMaxAlbumCount) { - const auto badIt = ranges::find( - files, - PreparedFile::AlbumType::None, - [](const PreparedFile &file) { return file.type; }); - albumIsPossible = (badIt == files.end()); - } else { - albumIsPossible = false; - } -} - -bool PreparedList::canAddCaption(bool isAlbum, bool compressImages) const { - const auto isSticker = [&] { - if (files.empty()) { - return false; - } - return Core::IsMimeSticker(files.front().mime) - || files.front().path.endsWith( - qstr(".tgs"), - Qt::CaseInsensitive); - }; - return isAlbum || (files.size() == 1 && !isSticker()); -} - -int MaxAlbumItems() { - return kMaxAlbumCount; -} - } // namespace Storage diff --git a/Telegram/SourceFiles/storage/storage_media_prepare.h b/Telegram/SourceFiles/storage/storage_media_prepare.h index 1cdfa3082..d07d90abe 100644 --- a/Telegram/SourceFiles/storage/storage_media_prepare.h +++ b/Telegram/SourceFiles/storage/storage_media_prepare.h @@ -10,7 +10,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/file_utilities.h" #include "lang/lang_keys.h" -struct FileMediaInformation; +namespace Ui { +struct PreparedFileInformation; +struct PreparedFile; +struct PreparedList; +} // namespace Ui namespace Storage { @@ -21,72 +25,19 @@ enum class MimeDataState { Image, }; +std::optional PreparedFileFromFilesDialog( + FileDialog::OpenResult &&result, + bool isAlbum, + Fn)> errorCallback, + int previewWidth); MimeDataState ComputeMimeDataState(const QMimeData *data); - -struct PreparedFile { - enum class AlbumType { - None, - Photo, - Video, - }; - - PreparedFile(const QString &path); - PreparedFile(PreparedFile &&other); - PreparedFile &operator=(PreparedFile &&other); - ~PreparedFile(); - - QString path; - QByteArray content; - QString mime; - std::unique_ptr information; - QImage preview; - QSize shownDimensions; - AlbumType type = AlbumType::None; - -}; - -struct PreparedList { - enum class Error { - None, - NonLocalUrl, - Directory, - EmptyFile, - TooLargeFile, - }; - - PreparedList() = default; - PreparedList(Error error, QString errorData) - : error(error) - , errorData(errorData) { - } - static PreparedList Reordered( - PreparedList &&list, - std::vector order); - static std::optional PreparedFileFromFilesDialog( - FileDialog::OpenResult &&result, - bool isAlbum, - Fn)> errorCallback, - int previewWidth); - void mergeToEnd(PreparedList &&other, bool cutToAlbumSize = false); - - bool canAddCaption(bool isAlbum, bool compressImages) const; - - Error error = Error::None; - QString errorData; - std::vector files; - bool allFilesForCompress = true; - bool albumIsPossible = false; - -}; - bool ValidateDragData(not_null data, bool isAlbum); bool ValidateThumbDimensions(int width, int height); -PreparedList PrepareMediaList(const QList &files, int previewWidth); -PreparedList PrepareMediaList(const QStringList &files, int previewWidth); -PreparedList PrepareMediaFromImage( +Ui::PreparedList PrepareMediaList(const QList &files, int previewWidth); +Ui::PreparedList PrepareMediaList(const QStringList &files, int previewWidth); +Ui::PreparedList PrepareMediaFromImage( QImage &&image, QByteArray &&content, int previewWidth); -int MaxAlbumItems(); } // namespace Storage diff --git a/Telegram/SourceFiles/support/support_helper.cpp b/Telegram/SourceFiles/support/support_helper.cpp index 82c2fd328..c660a5de7 100644 --- a/Telegram/SourceFiles/support/support_helper.cpp +++ b/Telegram/SourceFiles/support/support_helper.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/abstract_box.h" #include "ui/toast/toast.h" #include "ui/widgets/input_fields.h" +#include "ui/chat/attach/attach_prepare.h" #include "ui/text/text_entity.h" #include "ui/text/text_options.h" #include "chat_helpers/message_field.h" diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp new file mode 100644 index 000000000..94a03753d --- /dev/null +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp @@ -0,0 +1,91 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "ui/chat/attach/attach_prepare.h" + +#include "core/mime_type.h" + +namespace Ui { +namespace { + +constexpr auto kMaxAlbumCount = 10; + +} // namespace + +PreparedFile::PreparedFile(const QString &path) : path(path) { +} + +PreparedFile::PreparedFile(PreparedFile &&other) = default; + +PreparedFile &PreparedFile::operator=(PreparedFile && other) = default; + +PreparedFile::~PreparedFile() = default; + +PreparedList PreparedList::Reordered( + PreparedList &&list, + std::vector order) { + Expects(list.error == PreparedList::Error::None); + Expects(list.files.size() == order.size()); + + auto result = PreparedList(list.error, list.errorData); + result.albumIsPossible = list.albumIsPossible; + result.allFilesForCompress = list.allFilesForCompress; + result.files.reserve(list.files.size()); + for (auto index : order) { + result.files.push_back(std::move(list.files[index])); + } + return result; +} + +void PreparedList::mergeToEnd(PreparedList &&other, bool cutToAlbumSize) { + if (error != Error::None) { + return; + } + if (other.error != Error::None) { + error = other.error; + errorData = other.errorData; + return; + } + allFilesForCompress = allFilesForCompress && other.allFilesForCompress; + files.reserve(std::min( + size_t(cutToAlbumSize ? kMaxAlbumCount : INT_MAX), + files.size() + other.files.size())); + for (auto &file : other.files) { + if (cutToAlbumSize && files.size() == kMaxAlbumCount) { + break; + } + files.push_back(std::move(file)); + } + if (files.size() > 1 && files.size() <= kMaxAlbumCount) { + const auto badIt = ranges::find( + files, + PreparedFile::AlbumType::None, + [](const PreparedFile &file) { return file.type; }); + albumIsPossible = (badIt == files.end()); + } else { + albumIsPossible = false; + } +} + +bool PreparedList::canAddCaption(bool isAlbum, bool compressImages) const { + const auto isSticker = [&] { + if (files.empty()) { + return false; + } + return Core::IsMimeSticker(files.front().mime) + || files.front().path.endsWith( + qstr(".tgs"), + Qt::CaseInsensitive); + }; + return isAlbum || (files.size() == 1 && !isSticker()); +} + +int MaxAlbumItems() { + return kMaxAlbumCount; +} + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h new file mode 100644 index 000000000..2853996cd --- /dev/null +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h @@ -0,0 +1,85 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +namespace Ui { + +struct PreparedFileInformation { + struct Image { + QImage data; + bool animated = false; + }; + struct Song { + int duration = -1; + QString title; + QString performer; + QImage cover; + }; + struct Video { + bool isGifv = false; + bool supportsStreaming = false; + int duration = -1; + QImage thumbnail; + }; + + QString filemime; + std::variant media; +}; + +struct PreparedFile { + enum class AlbumType { + None, + Photo, + Video, + }; + + PreparedFile(const QString &path); + PreparedFile(PreparedFile &&other); + PreparedFile &operator=(PreparedFile &&other); + ~PreparedFile(); + + QString path; + QByteArray content; + QString mime; + std::unique_ptr information; + QImage preview; + QSize shownDimensions; + AlbumType type = AlbumType::None; +}; + +struct PreparedList { + enum class Error { + None, + NonLocalUrl, + Directory, + EmptyFile, + TooLargeFile, + }; + + PreparedList() = default; + PreparedList(Error error, QString errorData) + : error(error) + , errorData(errorData) { + } + [[nodiscard]] static PreparedList Reordered( + PreparedList &&list, + std::vector order); + void mergeToEnd(PreparedList &&other, bool cutToAlbumSize = false); + + [[nodiscard]] bool canAddCaption(bool isAlbum, bool compressImages) const; + + Error error = Error::None; + QString errorData; + std::vector files; + bool allFilesForCompress = true; + bool albumIsPossible = false; +}; + +[[nodiscard]] int MaxAlbumItems(); + +} // namespace Ui