Move PreparedFile/PreparedList to td_ui.

This commit is contained in:
John Preston 2020-10-13 15:07:53 +03:00
parent 39cf51c066
commit b3b11bd9e7
25 changed files with 358 additions and 302 deletions

View file

@ -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<SendingAlbum> 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");

View file

@ -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<SendingAlbum> album,
@ -404,7 +407,7 @@ public:
const SendAction &action);
void editMedia(
Storage::PreparedList &&list,
Ui::PreparedList &&list,
SendMediaType type,
TextWithTags &&caption,
const SendAction &action,

View file

@ -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<const QMimeData*> 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<InformBox>(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<const QMimeData*> 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<const QMimeData*> 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<Info::Image>(fileMedia)) {
return !Storage::ValidateThumbDimensions(

View file

@ -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;

View file

@ -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<QUrl> &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<void(Storage::PreparedList)> callback) {
Fn<void(Ui::PreparedList)> callback) {
auto showBoxErrorCallback = [](tr::phrase<> text) {
Ui::show(Box<InformBox>(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<Window::SessionController*> 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<int> 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<void()> editCallback,
@ -287,7 +288,7 @@ private:
};
AlbumThumb::AlbumThumb(
const Storage::PreparedFile &file,
const Ui::PreparedFile &file,
const Ui::GroupMediaLayout &layout,
QWidget *parent,
Fn<void()> 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<Window::SessionController*> 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<FileMediaInformation::Image>(
if (const auto image = std::get_if<Ui::PreparedFileInformation::Image>(
&file.information->media)) {
preview = image->data;
animated = animationPreview = image->animated;
} else if (const auto video = std::get_if<FileMediaInformation::Video>(
} else if (const auto video = std::get_if<Ui::PreparedFileInformation::Video>(
&file.information->media)) {
preview = video->thumbnail;
animated = true;
@ -970,7 +971,7 @@ rpl::producer<int> 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<FileMediaInformation::Image>(
if (const auto image = std::get_if<Ui::PreparedFileInformation::Image>(
&file.information->media)) {
preview = image->data;
} else if (const auto video = std::get_if<FileMediaInformation::Video>(
} else if (const auto video = std::get_if<Ui::PreparedFileInformation::Video>(
&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<FileMediaInformation::Song>(
if (const auto song = std::get_if<Ui::PreparedFileInformation::Song>(
&file.information->media)) {
songTitle = song->title;
songPerformer = song->performer;
@ -1118,7 +1119,7 @@ rpl::producer<int> SingleFilePreview::desiredHeightValue() const {
}
rpl::producer<QString> 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<int> _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<Window::SessionController*> 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<const QMimeData*> 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<const QMimeData*> data) {
const auto urls = data->hasUrls() ? data->urls() : QList<QUrl>();
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<const QMimeData*> 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;

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <rpl/variable.h>
#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<Window::SessionController*> controller,
Storage::PreparedList &&list,
Ui::PreparedList &&list,
const TextWithTags &caption,
CompressConfirm compressed,
SendLimit limit,
@ -68,7 +69,7 @@ public:
void setConfirmedCallback(
Fn<void(
Storage::PreparedList &&list,
Ui::PreparedList &&list,
SendFilesWay way,
TextWithTags &&caption,
Api::SendOptions options,
@ -127,7 +128,7 @@ private:
bool canAddFiles(not_null<const QMimeData*> data) const;
bool addFiles(not_null<const QMimeData*> 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<void(
Storage::PreparedList &&list,
Ui::PreparedList &&list,
SendFilesWay way,
TextWithTags &&caption,
Api::SendOptions options,

View file

@ -19,10 +19,10 @@ MimeType::MimeType(Known type) : _type(type) {
QStringList MimeType::globPatterns() const {
switch (_type) {
case Known::WebP: return QStringList(qsl("*.webp"));
case Known::Tgs: return QStringList(qsl("*.tgs"));
case Known::TDesktopTheme: return QStringList(qsl("*.tdesktop-theme"));
case Known::TDesktopPalette: return QStringList(qsl("*.tdesktop-palette"));
case Known::WebP: return QStringList(u"*.webp"_q);
case Known::Tgs: return QStringList(u"*.tgs"_q);
case Known::TDesktopTheme: return QStringList(u"*.tdesktop-theme"_q);
case Known::TDesktopPalette: return QStringList(u"*.tdesktop-palette"_q);
default: break;
}
return _typeStruct.globPatterns();
@ -30,10 +30,10 @@ QStringList MimeType::globPatterns() const {
QString MimeType::filterString() const {
switch (_type) {
case Known::WebP: return qsl("WebP image (*.webp)");
case Known::Tgs: return qsl("Telegram sticker (*.tgs)");
case Known::TDesktopTheme: return qsl("Theme files (*.tdesktop-theme)");
case Known::TDesktopPalette: return qsl("Palette files (*.tdesktop-palette)");
case Known::WebP: return u"WebP image (*.webp)"_q;
case Known::Tgs: return u"Telegram sticker (*.tgs)"_q;
case Known::TDesktopTheme: return u"Theme files (*.tdesktop-theme)"_q;
case Known::TDesktopPalette: return u"Palette files (*.tdesktop-palette)"_q;
default: break;
}
return _typeStruct.filterString();
@ -41,10 +41,10 @@ QString MimeType::filterString() const {
QString MimeType::name() const {
switch (_type) {
case Known::WebP: return qsl("image/webp");
case Known::Tgs: return qsl("application/x-tgsticker");
case Known::TDesktopTheme: return qsl("application/x-tdesktop-theme");
case Known::TDesktopPalette: return qsl("application/x-tdesktop-palette");
case Known::WebP: return u"image/webp"_q;
case Known::Tgs: return u"application/x-tgsticker"_q;
case Known::TDesktopTheme: return u"application/x-tdesktop-theme"_q;
case Known::TDesktopPalette: return u"application/x-tdesktop-palette"_q;
default: break;
}
return _typeStruct.name();
@ -103,11 +103,11 @@ MimeType MimeTypeForData(const QByteArray &data) {
}
bool IsMimeStickerAnimated(const QString &mime) {
return mime == qsl("application/x-tgsticker");
return (mime == u"application/x-tgsticker"_q);
}
bool IsMimeSticker(const QString &mime) {
return mime == qsl("image/webp")
return (mime == u"image/webp"_q)
|| IsMimeStickerAnimated(mime);
}

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <QtCore/QFileInfo>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QMimeType>

View file

@ -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,

View file

@ -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,

View file

@ -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<QString> 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:

View file

@ -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<const QMimeData*> 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,

View file

@ -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:

View file

@ -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<const QMimeData*> 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,

View file

@ -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) {

View file

@ -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 <QtCore/QTimer>
@ -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 {

View file

@ -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);

View file

@ -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 <QtCore/QTimer>
@ -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();

View file

@ -489,7 +489,7 @@ FileLoadTask::FileLoadTask(
not_null<Main::Session*> session,
const QString &filepath,
const QByteArray &content,
std::unique_ptr<FileMediaInformation> information,
std::unique_ptr<Ui::PreparedFileInformation> information,
SendMediaType type,
const FileLoadTo &to,
const TextWithTags &caption,
@ -528,11 +528,13 @@ FileLoadTask::FileLoadTask(
, _caption(caption) {
}
std::unique_ptr<FileMediaInformation> FileLoadTask::ReadMediaInformation(
FileLoadTask::~FileLoadTask() = default;
std::unique_ptr<Ui::PreparedFileInformation> FileLoadTask::ReadMediaInformation(
const QString &filepath,
const QByteArray &content,
const QString &filemime) {
auto result = std::make_unique<FileMediaInformation>();
auto result = std::make_unique<Ui::PreparedFileInformation>();
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<FileMediaInformation> &result) {
std::unique_ptr<Ui::PreparedFileInformation> &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<FileMediaInformation> &result) {
std::unique_ptr<Ui::PreparedFileInformation> &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<FileMediaInformation> &result) {
std::unique_ptr<Ui::PreparedFileInformation> &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<FileMediaInformation> &result) {
std::unique_ptr<Ui::PreparedFileInformation> &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<FileMediaInformation::Image>(
if (auto image = std::get_if<Ui::PreparedFileInformation::Image>(
&_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<FileMediaInformation::Image>(
if (auto image = std::get_if<Ui::PreparedFileInformation::Image>(
&_information->media)) {
fullimage = base::take(image->data);
}
@ -757,7 +759,7 @@ void FileLoadTask::process() {
}
} else {
if (_information) {
if (auto image = std::get_if<FileMediaInformation::Image>(
if (auto image = std::get_if<Ui::PreparedFileInformation::Image>(
&_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<FileMediaInformation::Song>(
if (auto song = std::get_if<Ui::PreparedFileInformation::Song>(
&_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<FileMediaInformation::Video>(
} else if (auto video = std::get_if<Ui::PreparedFileInformation::Video>(
&_information->media)) {
isVideo = true;
auto coverWidth = video->thumbnail.width();
@ -996,6 +998,11 @@ FileLoadResult *FileLoadTask::peekResult() const {
return _result.get();
}
std::unique_ptr<Ui::PreparedFileInformation> FileLoadTask::readMediaInformation(
const QString &filemime) const {
return ReadMediaInformation(_filepath, _content, filemime);
}
void FileLoadTask::removeFromAlbum() {
if (!_album) {
return;

View file

@ -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<v::null_t, Image, Song, Video> media;
};
class FileLoadTask final : public Task {
public:
static std::unique_ptr<FileMediaInformation> ReadMediaInformation(
static std::unique_ptr<Ui::PreparedFileInformation> ReadMediaInformation(
const QString &filepath,
const QByteArray &content,
const QString &filemime);
static bool FillImageInformation(
QImage &&image,
bool animated,
std::unique_ptr<FileMediaInformation> &result);
std::unique_ptr<Ui::PreparedFileInformation> &result);
FileLoadTask(
not_null<Main::Session*> session,
const QString &filepath,
const QByteArray &content,
std::unique_ptr<FileMediaInformation> information,
std::unique_ptr<Ui::PreparedFileInformation> 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<FileMediaInformation> &result);
std::unique_ptr<Ui::PreparedFileInformation> &result);
static bool CheckForVideo(
const QString &filepath,
const QByteArray &content,
std::unique_ptr<FileMediaInformation> &result);
std::unique_ptr<Ui::PreparedFileInformation> &result);
static bool CheckForImage(
const QString &filepath,
const QByteArray &content,
std::unique_ptr<FileMediaInformation> &result);
std::unique_ptr<Ui::PreparedFileInformation> &result);
template <typename Mimes, typename Extensions>
static bool CheckMimeOrExtensions(const QString &filepath, const QString &filemime, Mimes &mimes, Extensions &extensions);
std::unique_ptr<FileMediaInformation> readMediaInformation(const QString &filemime) const {
return ReadMediaInformation(_filepath, _content, filemime);
}
std::unique_ptr<Ui::PreparedFileInformation> readMediaInformation(const QString &filemime) const;
void removeFromAlbum();
uint64 _id = 0;
@ -328,7 +306,7 @@ private:
const std::shared_ptr<SendingAlbum> _album;
QString _filepath;
QByteArray _content;
std::unique_ptr<FileMediaInformation> _information;
std::unique_ptr<Ui::PreparedFileInformation> _information;
int32 _duration = 0;
VoiceWaveform _waveform;
SendMediaType _type;

View file

@ -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 <QtCore/QSemaphore>
@ -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<Image>(
&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<FileMediaInformation>();
file.information = std::make_unique<PreparedFileInformation>();
const auto animated = false;
FileLoadTask::FillImageInformation(
std::move(image),
@ -296,7 +290,7 @@ PreparedList PrepareMediaFromImage(
return result;
}
std::optional<PreparedList> PreparedList::PreparedFileFromFilesDialog(
std::optional<PreparedList> PreparedFileFromFilesDialog(
FileDialog::OpenResult &&result,
bool isAlbum,
Fn<void(tr::phrase<>)> errorCallback,
@ -347,7 +341,7 @@ std::optional<PreparedList> 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> PreparedList::PreparedFileFromFilesDialog(
return std::nullopt;
}
PreparedList PreparedList::Reordered(
PreparedList &&list,
std::vector<int> 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

View file

@ -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<Ui::PreparedList> PreparedFileFromFilesDialog(
FileDialog::OpenResult &&result,
bool isAlbum,
Fn<void(tr::phrase<>)> 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<FileMediaInformation> 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<int> order);
static std::optional<PreparedList> PreparedFileFromFilesDialog(
FileDialog::OpenResult &&result,
bool isAlbum,
Fn<void(tr::phrase<>)> 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<PreparedFile> files;
bool allFilesForCompress = true;
bool albumIsPossible = false;
};
bool ValidateDragData(not_null<const QMimeData*> data, bool isAlbum);
bool ValidateThumbDimensions(int width, int height);
PreparedList PrepareMediaList(const QList<QUrl> &files, int previewWidth);
PreparedList PrepareMediaList(const QStringList &files, int previewWidth);
PreparedList PrepareMediaFromImage(
Ui::PreparedList PrepareMediaList(const QList<QUrl> &files, int previewWidth);
Ui::PreparedList PrepareMediaList(const QStringList &files, int previewWidth);
Ui::PreparedList PrepareMediaFromImage(
QImage &&image,
QByteArray &&content,
int previewWidth);
int MaxAlbumItems();
} // namespace Storage

View file

@ -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"

View file

@ -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<int> 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

View file

@ -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<v::null_t, Image, Song, Video> 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<Ui::PreparedFileInformation> 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<int> order);
void mergeToEnd(PreparedList &&other, bool cutToAlbumSize = false);
[[nodiscard]] bool canAddCaption(bool isAlbum, bool compressImages) const;
Error error = Error::None;
QString errorData;
std::vector<PreparedFile> files;
bool allFilesForCompress = true;
bool albumIsPossible = false;
};
[[nodiscard]] int MaxAlbumItems();
} // namespace Ui