diff --git a/Telegram/SourceFiles/api/api_peer_photo.cpp b/Telegram/SourceFiles/api/api_peer_photo.cpp index c70ef4491..9c8a470fa 100644 --- a/Telegram/SourceFiles/api/api_peer_photo.cpp +++ b/Telegram/SourceFiles/api/api_peer_photo.cpp @@ -34,7 +34,7 @@ namespace { constexpr auto kSharedMediaLimit = 100; -[[nodiscard]] SendMediaReady PreparePeerPhoto( +[[nodiscard]] std::shared_ptr PreparePeerPhoto( MTP::DcId dcId, PeerId peerId, QImage &&image) { @@ -80,24 +80,17 @@ constexpr auto kSharedMediaLimit = 100; MTPVector(), MTP_int(dcId)); - QString file, filename; - int64 filesize = 0; - QByteArray data; - - return SendMediaReady( - SendMediaType::Photo, - file, - filename, - filesize, - data, - id, - id, - u"jpg"_q, - peerId, - photo, - photoThumbs, - MTP_documentEmpty(MTP_long(0)), - jpeg); + auto result = MakePreparedFile({ + .id = id, + .type = SendMediaType::Photo, + }); + result->type = SendMediaType::Photo; + result->setFileData(jpeg); + result->thumbId = id; + result->thumbname = "thumb.jpg"; + result->photo = photo; + result->photoThumbs = photoThumbs; + return result; } [[nodiscard]] std::optional PrepareMtpMarkup( @@ -239,7 +232,7 @@ void PeerPhoto::upload( _api.instance().mainDcId(), peer->id, base::take(photo.image)); - _session->uploader().uploadMedia(fakeId, ready); + _session->uploader().upload(fakeId, ready); } } diff --git a/Telegram/SourceFiles/api/api_ringtones.cpp b/Telegram/SourceFiles/api/api_ringtones.cpp index 87522bf58..307ba580a 100644 --- a/Telegram/SourceFiles/api/api_ringtones.cpp +++ b/Telegram/SourceFiles/api/api_ringtones.cpp @@ -24,16 +24,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Api { namespace { -SendMediaReady PrepareRingtoneDocument( +std::shared_ptr PrepareRingtoneDocument( MTP::DcId dcId, const QString &filename, const QString &filemime, const QByteArray &content) { + const auto id = base::RandomValue(); auto attributes = QVector( 1, MTP_documentAttributeFilename(MTP_string(filename))); - const auto id = base::RandomValue(); - const auto document = MTP_document( + + auto result = MakePreparedFile({ + .id = id, + .type = SendMediaType::File, + }); + result->filename = filename; + result->content = content; + result->filesize = content.size(); + result->setFileData(content); + result->document = MTP_document( MTP_flags(0), MTP_long(id), MTP_long(0), @@ -45,21 +54,7 @@ SendMediaReady PrepareRingtoneDocument( MTPVector(), MTP_int(dcId), MTP_vector(std::move(attributes))); - - return SendMediaReady( - SendMediaType::File, - QString(), // filepath - filename, - content.size(), - content, - id, - 0, - QString(), - PeerId(), - MTP_photoEmpty(MTP_long(0)), - PreparedPhotoThumbs(), - document, - QByteArray()); + return result; } } // namespace @@ -102,7 +97,7 @@ void Ringtones::upload( _uploads.erase(already); } _uploads.emplace(fakeId, uploadedData); - _session->uploader().uploadMedia(fakeId, ready); + _session->uploader().upload(fakeId, ready); } void Ringtones::ready(const FullMsgId &msgId, const MTPInputFile &file) { diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp index 72bd06b3d..d91943fe0 100644 --- a/Telegram/SourceFiles/api/api_sending.cpp +++ b/Telegram/SourceFiles/api/api_sending.cpp @@ -353,7 +353,7 @@ void FillMessagePostFlags( void SendConfirmedFile( not_null session, - const std::shared_ptr &file) { + const std::shared_ptr &file) { const auto isEditing = (file->type != SendMediaType::Audio) && (file->to.replaceMediaOf != 0); const auto newId = FullMsgId( diff --git a/Telegram/SourceFiles/api/api_sending.h b/Telegram/SourceFiles/api/api_sending.h index e17c66f3e..2fdbad843 100644 --- a/Telegram/SourceFiles/api/api_sending.h +++ b/Telegram/SourceFiles/api/api_sending.h @@ -14,7 +14,7 @@ class Session; class History; class PhotoData; class DocumentData; -struct FileLoadResult; +struct FilePrepareResult; namespace Api { @@ -40,6 +40,6 @@ void FillMessagePostFlags( void SendConfirmedFile( not_null session, - const std::shared_ptr &file); + const std::shared_ptr &file); } // namespace Api diff --git a/Telegram/SourceFiles/boxes/background_preview_box.cpp b/Telegram/SourceFiles/boxes/background_preview_box.cpp index 3a9917719..a112c478a 100644 --- a/Telegram/SourceFiles/boxes/background_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/background_preview_box.cpp @@ -593,11 +593,11 @@ void BackgroundPreviewBox::uploadForPeer(bool both) { const auto ready = Window::Theme::PrepareWallPaper( session->mainDcId(), _paper.localThumbnail()->original()); - const auto documentId = ready.id; + const auto documentId = ready->id; _uploadId = FullMsgId( session->userPeerId(), session->data().nextLocalMessageId()); - session->uploader().uploadMedia(_uploadId, ready); + session->uploader().upload(_uploadId, ready); if (_uploadLifetime) { return; } diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 43966331e..b4d8bb49c 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -18,7 +18,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/fields/input_field.h" #include "mtproto/sender.h" -struct FileLoadResult; enum class SendMediaType; class MessageLinksParser; struct InlineBotQuery; diff --git a/Telegram/SourceFiles/iv/iv_data.cpp b/Telegram/SourceFiles/iv/iv_data.cpp index bbcca0b2c..5258e6c9f 100644 --- a/Telegram/SourceFiles/iv/iv_data.cpp +++ b/Telegram/SourceFiles/iv/iv_data.cpp @@ -25,7 +25,7 @@ QByteArray GeoPointId(Geo point) { const auto lon = int(point.lon * 1000000); const auto combined = (std::uint64_t(std::uint32_t(lat)) << 32) | std::uint64_t(std::uint32_t(lon)); - return QByteArray::number(combined) + return QByteArray::number(quint64(combined)) + ',' + QByteArray::number(point.access); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 10bea63d4..809086765 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -16,7 +16,6 @@ struct HistoryMessageMarkupButton; class MainWindow; class HistoryWidget; class StackItem; -struct FileLoadResult; class History; class Image; diff --git a/Telegram/SourceFiles/passport/passport_form_controller.cpp b/Telegram/SourceFiles/passport/passport_form_controller.cpp index 684163163..980888ffb 100644 --- a/Telegram/SourceFiles/passport/passport_form_controller.cpp +++ b/Telegram/SourceFiles/passport/passport_form_controller.cpp @@ -1581,14 +1581,10 @@ void FormController::uploadEncryptedFile( &session(), std::make_unique(std::move(data))); - auto prepared = std::make_shared( - TaskId(), - file.uploadData->fileId, - FileLoadTo(PeerId(), Api::SendOptions(), FullReplyTo(), MsgId()), - TextWithTags(), - false, - std::shared_ptr(nullptr)); - prepared->type = SendMediaType::Secure; + auto prepared = MakePreparedFile({ + .id = file.uploadData->fileId, + .type = SendMediaType::Secure, + }); prepared->content = QByteArray::fromRawData( reinterpret_cast(file.uploadData->bytes.data()), file.uploadData->bytes.size()); diff --git a/Telegram/SourceFiles/storage/file_upload.cpp b/Telegram/SourceFiles/storage/file_upload.cpp index c40396955..e0c7f8b57 100644 --- a/Telegram/SourceFiles/storage/file_upload.cpp +++ b/Telegram/SourceFiles/storage/file_upload.cpp @@ -59,22 +59,15 @@ constexpr auto kKillSessionTimeout = 15 * crl::time(1000); } // namespace struct Uploader::File { - File(const SendMediaReady &media); - File(const std::shared_ptr &file); + explicit File(const std::shared_ptr &file); void setDocSize(int64 size); bool setPartSize(uint32 partSize); - std::shared_ptr file; - SendMediaReady media; + std::shared_ptr file; int32 partsCount = 0; mutable int64 fileSentSize = 0; - uint64 id() const; - SendMediaType type() const; - uint64 thumbId() const; - const QString &filename() const; - HashMd5 md5Hash; std::unique_ptr docFile; @@ -85,27 +78,15 @@ struct Uploader::File { }; -Uploader::File::File(const SendMediaReady &media) : media(media) { - partsCount = media.parts.size(); - if (type() == SendMediaType::File - || type() == SendMediaType::ThemeFile - || type() == SendMediaType::Audio) { - setDocSize(media.file.isEmpty() - ? media.data.size() - : media.filesize); - } else { - docSize = docPartSize = docPartsCount = 0; - } -} -Uploader::File::File(const std::shared_ptr &file) +Uploader::File::File(const std::shared_ptr &file) : file(file) { - partsCount = (type() == SendMediaType::Photo - || type() == SendMediaType::Secure) + partsCount = (file->type == SendMediaType::Photo + || file->type == SendMediaType::Secure) ? file->fileparts.size() : file->thumbparts.size(); - if (type() == SendMediaType::File - || type() == SendMediaType::ThemeFile - || type() == SendMediaType::Audio) { + if (file->type == SendMediaType::File + || file->type == SendMediaType::ThemeFile + || file->type == SendMediaType::Audio) { setDocSize(file->filesize); } else { docSize = docPartSize = docPartsCount = 0; @@ -134,22 +115,6 @@ bool Uploader::File::setPartSize(uint32 partSize) { return (docPartsCount <= kDocumentMaxPartsCountDefault); } -uint64 Uploader::File::id() const { - return file ? file->id : media.id; -} - -SendMediaType Uploader::File::type() const { - return file ? file->type : media.type; -} - -uint64 Uploader::File::thumbId() const { - return file ? file->thumbId : media.thumbId; -} - -const QString &Uploader::File::filename() const { - return file ? file->filename : media.filename; -} - Uploader::Uploader(not_null api) : _api(api) , _nextTimer([=] { sendNext(); }) @@ -282,39 +247,9 @@ Main::Session &Uploader::session() const { return _api->session(); } -void Uploader::uploadMedia( - const FullMsgId &msgId, - const SendMediaReady &media) { - if (media.type == SendMediaType::Photo) { - session().data().processPhoto(media.photo, media.photoThumbs); - } else if (media.type == SendMediaType::File - || media.type == SendMediaType::ThemeFile - || media.type == SendMediaType::Audio) { - const auto document = media.photoThumbs.empty() - ? session().data().processDocument(media.document) - : session().data().processDocument( - media.document, - Images::FromImageInMemory( - media.photoThumbs.front().second.image, - "JPG", - media.photoThumbs.front().second.bytes)); - if (!media.data.isEmpty()) { - document->setDataAndCache(media.data); - if (media.type == SendMediaType::ThemeFile) { - document->checkWallPaperProperties(); - } - } - if (!media.file.isEmpty()) { - document->setLocation(Core::FileLocation(media.file)); - } - } - queue.emplace(msgId, File(media)); - sendNext(); -} - void Uploader::upload( const FullMsgId &msgId, - const std::shared_ptr &file) { + const std::shared_ptr &file) { if (file->type == SendMediaType::Photo) { const auto photo = session().data().processPhoto( file->photo, @@ -383,13 +318,13 @@ void Uploader::currentFailed() { } void Uploader::notifyFailed(FullMsgId id, const File &file) { - const auto type = file.type(); + const auto type = file.file->type; if (type == SendMediaType::Photo) { _photoFailed.fire_copy(id); } else if (type == SendMediaType::File || type == SendMediaType::ThemeFile || type == SendMediaType::Audio) { - const auto document = session().data().document(file.id()); + const auto document = session().data().document(file.file->id); if (document->uploading()) { document->status = FileUploadFailed; } @@ -439,18 +374,14 @@ void Uploader::sendNext() { } } - auto &parts = uploadingData.file - ? ((uploadingData.type() == SendMediaType::Photo - || uploadingData.type() == SendMediaType::Secure) - ? uploadingData.file->fileparts - : uploadingData.file->thumbparts) - : uploadingData.media.parts; - const auto partsOfId = uploadingData.file - ? ((uploadingData.type() == SendMediaType::Photo - || uploadingData.type() == SendMediaType::Secure) - ? uploadingData.file->id - : uploadingData.file->thumbId) - : uploadingData.media.thumbId; + auto &parts = (uploadingData.file->type == SendMediaType::Photo + || uploadingData.file->type == SendMediaType::Secure) + ? uploadingData.file->fileparts + : uploadingData.file->thumbparts; + const auto partsOfId = (uploadingData.file->type == SendMediaType::Photo + || uploadingData.file->type == SendMediaType::Secure) + ? uploadingData.file->id + : uploadingData.file->thumbId; if (parts.isEmpty()) { if (uploadingData.docSentParts >= uploadingData.docPartsCount) { if (requestsSent.empty() && docRequestsSent.empty()) { @@ -462,19 +393,17 @@ void Uploader::sendNext() { const auto attachedStickers = uploadingData.file ? uploadingData.file->attachedStickers : std::vector(); - if (uploadingData.type() == SendMediaType::Photo) { - auto photoFilename = uploadingData.filename(); + if (uploadingData.file->type == SendMediaType::Photo) { + auto photoFilename = uploadingData.file->filename; if (!photoFilename.endsWith(u".jpg"_q, Qt::CaseInsensitive)) { // Server has some extensions checking for inputMediaUploadedPhoto, // so force the extension to be .jpg anyway. It doesn't matter, // because the filename from inputFile is not used anywhere. photoFilename += u".jpg"_q; } - const auto md5 = uploadingData.file - ? uploadingData.file->filemd5 - : uploadingData.media.jpeg_md5; + const auto md5 = uploadingData.file->filemd5; const auto file = MTP_inputFile( - MTP_long(uploadingData.id()), + MTP_long(uploadingData.file->id), MTP_int(uploadingData.partsCount), MTP_string(photoFilename), MTP_bytes(md5)); @@ -487,34 +416,30 @@ void Uploader::sendNext() { .options = options, .edit = edit, }); - } else if (uploadingData.type() == SendMediaType::File - || uploadingData.type() == SendMediaType::ThemeFile - || uploadingData.type() == SendMediaType::Audio) { + } else if (uploadingData.file->type == SendMediaType::File + || uploadingData.file->type == SendMediaType::ThemeFile + || uploadingData.file->type == SendMediaType::Audio) { QByteArray docMd5(32, Qt::Uninitialized); hashMd5Hex(uploadingData.md5Hash.result(), docMd5.data()); const auto file = (uploadingData.docSize > kUseBigFilesFrom) ? MTP_inputFileBig( - MTP_long(uploadingData.id()), + MTP_long(uploadingData.file->id), MTP_int(uploadingData.docPartsCount), - MTP_string(uploadingData.filename())) + MTP_string(uploadingData.file->filename)) : MTP_inputFile( - MTP_long(uploadingData.id()), + MTP_long(uploadingData.file->id), MTP_int(uploadingData.docPartsCount), - MTP_string(uploadingData.filename()), + MTP_string(uploadingData.file->filename), MTP_bytes(docMd5)); const auto thumb = [&]() -> std::optional { if (!uploadingData.partsCount) { return std::nullopt; } - const auto thumbFilename = uploadingData.file - ? uploadingData.file->thumbname - : (u"thumb."_q + uploadingData.media.thumbExt); - const auto thumbMd5 = uploadingData.file - ? uploadingData.file->thumbmd5 - : uploadingData.media.jpeg_md5; + const auto thumbFilename = uploadingData.file->thumbname; + const auto thumbMd5 = uploadingData.file->thumbmd5; return MTP_inputFile( - MTP_long(uploadingData.thumbId()), + MTP_long(uploadingData.file->thumbId), MTP_int(uploadingData.partsCount), MTP_string(thumbFilename), MTP_bytes(thumbMd5)); @@ -529,10 +454,10 @@ void Uploader::sendNext() { .options = options, .edit = edit, }); - } else if (uploadingData.type() == SendMediaType::Secure) { + } else if (uploadingData.file->type == SendMediaType::Secure) { _secureReady.fire({ uploadingId, - uploadingData.id(), + uploadingData.file->id, uploadingData.partsCount }); } queue.erase(uploadingId); @@ -542,15 +467,11 @@ void Uploader::sendNext() { return; } - auto &content = uploadingData.file - ? uploadingData.file->content - : uploadingData.media.data; + auto &content = uploadingData.file->content; QByteArray toSend; if (content.isEmpty()) { if (!uploadingData.docFile) { - const auto filepath = uploadingData.file - ? uploadingData.file->filepath - : uploadingData.media.file; + const auto filepath = uploadingData.file->filepath; uploadingData.docFile = std::make_unique(filepath); if (!uploadingData.docFile->open(QIODevice::ReadOnly)) { currentFailed(); @@ -565,9 +486,9 @@ void Uploader::sendNext() { const auto offset = uploadingData.docSentParts * uploadingData.docPartSize; toSend = content.mid(offset, uploadingData.docPartSize); - if ((uploadingData.type() == SendMediaType::File - || uploadingData.type() == SendMediaType::ThemeFile - || uploadingData.type() == SendMediaType::Audio) + if ((uploadingData.file->type == SendMediaType::File + || uploadingData.file->type == SendMediaType::ThemeFile + || uploadingData.file->type == SendMediaType::Audio) && uploadingData.docSentParts <= kUseBigFilesFrom) { uploadingData.md5Hash.feed(toSend.constData(), toSend.size()); } @@ -581,7 +502,7 @@ void Uploader::sendNext() { mtpRequestId requestId; if (uploadingData.docSize > kUseBigFilesFrom) { requestId = _api->request(MTPupload_SaveBigFilePart( - MTP_long(uploadingData.id()), + MTP_long(uploadingData.file->id), MTP_int(uploadingData.docSentParts), MTP_int(uploadingData.docPartsCount), MTP_bytes(toSend) @@ -592,7 +513,7 @@ void Uploader::sendNext() { }).toDC(MTP::uploadDcId(todc)).send(); } else { requestId = _api->request(MTPupload_SaveFilePart( - MTP_long(uploadingData.id()), + MTP_long(uploadingData.file->id), MTP_int(uploadingData.docSentParts), MTP_bytes(toSend) )).done([=](const MTPBool &result, mtpRequestId requestId) { @@ -723,18 +644,18 @@ void Uploader::partLoaded(const MTPBool &result, mtpRequestId requestId) { } sentSize -= sentPartSize; sentSizes[dc] -= sentPartSize; - if (file.type() == SendMediaType::Photo) { + if (file.file->type == SendMediaType::Photo) { file.fileSentSize += sentPartSize; - const auto photo = session().data().photo(file.id()); + const auto photo = session().data().photo(file.file->id); if (photo->uploading() && file.file) { photo->uploadingData->size = file.file->partssize; photo->uploadingData->offset = file.fileSentSize; } _photoProgress.fire_copy(fullId); - } else if (file.type() == SendMediaType::File - || file.type() == SendMediaType::ThemeFile - || file.type() == SendMediaType::Audio) { - const auto document = session().data().document(file.id()); + } else if (file.file->type == SendMediaType::File + || file.file->type == SendMediaType::ThemeFile + || file.file->type == SendMediaType::Audio) { + const auto document = session().data().document(file.file->id); if (document->uploading()) { const auto doneParts = file.docSentParts - int(docRequestsSent.size()); @@ -743,7 +664,7 @@ void Uploader::partLoaded(const MTPBool &result, mtpRequestId requestId) { doneParts * file.docPartSize); } _documentProgress.fire_copy(fullId); - } else if (file.type() == SendMediaType::Secure) { + } else if (file.file->type == SendMediaType::Secure) { file.fileSentSize += sentPartSize; _secureProgress.fire_copy({ fullId, diff --git a/Telegram/SourceFiles/storage/file_upload.h b/Telegram/SourceFiles/storage/file_upload.h index 2e68307b9..4347e5c03 100644 --- a/Telegram/SourceFiles/storage/file_upload.h +++ b/Telegram/SourceFiles/storage/file_upload.h @@ -12,8 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mtproto/facade.h" class ApiWrap; -struct FileLoadResult; -struct SendMediaReady; +struct FilePrepareResult; namespace Api { enum class SendProgressType; @@ -58,10 +57,9 @@ public: return uploadingId; } - void uploadMedia(const FullMsgId &msgId, const SendMediaReady &image); void upload( const FullMsgId &msgId, - const std::shared_ptr &file); + const std::shared_ptr &file); void cancel(const FullMsgId &msgId); void pause(const FullMsgId &msgId); diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp index c26b68458..192c7c112 100644 --- a/Telegram/SourceFiles/storage/localimageloader.cpp +++ b/Telegram/SourceFiles/storage/localimageloader.cpp @@ -222,42 +222,6 @@ int PhotoSideLimit() { return PhotoSideLimit(SendLargePhotos.value()); } -SendMediaReady::SendMediaReady( - SendMediaType type, - const QString &file, - const QString &filename, - int64 filesize, - const QByteArray &data, - const uint64 &id, - const uint64 &thumbId, - const QString &thumbExt, - const PeerId &peer, - const MTPPhoto &photo, - const PreparedPhotoThumbs &photoThumbs, - const MTPDocument &document, - const QByteArray &jpeg) -: type(type) -, file(file) -, filename(filename) -, filesize(filesize) -, data(data) -, thumbExt(thumbExt) -, id(id) -, thumbId(thumbId) -, peer(peer) -, photo(photo) -, document(document) -, photoThumbs(photoThumbs) { - if (!jpeg.isEmpty()) { - int32 size = jpeg.size(); - for (int32 i = 0, part = 0; i < size; i += kPhotoUploadPartSize, ++part) { - parts.insert(part, jpeg.mid(i, kPhotoUploadPartSize)); - } - jpeg_md5.resize(32); - hashMd5Hex(jpeg.constData(), jpeg.size(), jpeg_md5.data()); - } -} - TaskQueue::TaskQueue(crl::time stopTimeoutMs) { if (stopTimeoutMs > 0) { _stopTimer = new QTimer(this); @@ -455,22 +419,17 @@ SendingAlbum::Item::Item(TaskId taskId) : taskId(taskId) { } -FileLoadResult::FileLoadResult( - TaskId taskId, - uint64 id, - const FileLoadTo &to, - const TextWithTags &caption, - bool spoiler, - std::shared_ptr album) -: taskId(taskId) -, id(id) -, to(to) -, album(std::move(album)) -, caption(caption) -, spoiler(spoiler) { +FilePrepareResult::FilePrepareResult(FilePrepareDescriptor &&descriptor) +: taskId(descriptor.taskId) +, id(descriptor.id) +, to(std::move(descriptor.to)) +, album(std::move(descriptor.album)) +, type(descriptor.type) +, caption(std::move(descriptor.caption)) +, spoiler(descriptor.spoiler) { } -void FileLoadResult::setFileData(const QByteArray &filedata) { +void FilePrepareResult::setFileData(const QByteArray &filedata) { if (filedata.isEmpty()) { partssize = 0; } else { @@ -483,7 +442,7 @@ void FileLoadResult::setFileData(const QByteArray &filedata) { } } -void FileLoadResult::setThumbData(const QByteArray &thumbdata) { +void FilePrepareResult::setThumbData(const QByteArray &thumbdata) { if (!thumbdata.isEmpty()) { thumbbytes = thumbdata; int32 size = thumbdata.size(); @@ -495,6 +454,11 @@ void FileLoadResult::setThumbData(const QByteArray &thumbdata) { } } +std::shared_ptr MakePreparedFile( + FilePrepareDescriptor &&descriptor) { + return std::make_shared(std::move(descriptor)); +} + FileLoadTask::FileLoadTask( not_null session, const QString &filepath, @@ -710,13 +674,14 @@ bool FileLoadTask::FillImageInformation( } void FileLoadTask::process(Args &&args) { - _result = std::make_shared( - id(), - _id, - _to, - _caption, - _spoiler, - _album); + _result = MakePreparedFile({ + .taskId = id(), + .id = _id, + .to = _to, + .caption = _caption, + .spoiler = _spoiler, + .album = _album, + }); QString filename, filemime; qint64 filesize = 0; @@ -1062,7 +1027,7 @@ void FileLoadTask::finish() { } } -FileLoadResult *FileLoadTask::peekResult() const { +FilePrepareResult *FileLoadTask::peekResult() const { return _result.get(); } diff --git a/Telegram/SourceFiles/storage/localimageloader.h b/Telegram/SourceFiles/storage/localimageloader.h index d2e64b536..8b3b7bca7 100644 --- a/Telegram/SourceFiles/storage/localimageloader.h +++ b/Telegram/SourceFiles/storage/localimageloader.h @@ -36,43 +36,8 @@ enum class SendMediaType { Secure, }; -using UploadFileParts = QMap; -struct SendMediaReady { - SendMediaReady() = default; // temp - SendMediaReady( - SendMediaType type, - const QString &file, - const QString &filename, - int64 filesize, - const QByteArray &data, - const uint64 &id, - const uint64 &thumbId, - const QString &thumbExt, - const PeerId &peer, - const MTPPhoto &photo, - const PreparedPhotoThumbs &photoThumbs, - const MTPDocument &document, - const QByteArray &jpeg); - - SendMediaType type; - QString file, filename; - int64 filesize = 0; - QByteArray data; - QString thumbExt; - uint64 id, thumbId; // id always file-id of media, thumbId is file-id of thumb ( == id for photos) - PeerId peer; - - MTPPhoto photo; - MTPDocument document; - PreparedPhotoThumbs photoThumbs; - UploadFileParts parts; - QByteArray jpeg_md5; - - QString caption; - -}; - using TaskId = void*; // no interface, just id +inline constexpr auto kEmptyTaskId = TaskId(); class Task { public: @@ -144,7 +109,7 @@ struct SendingAlbum { struct Item { explicit Item(TaskId taskId); - TaskId taskId; + TaskId taskId = kEmptyTaskId; uint64 randomId = 0; FullMsgId msgId; std::optional media; @@ -182,17 +147,21 @@ struct FileLoadTo { MsgId replaceMediaOf; }; -struct FileLoadResult { - FileLoadResult( - TaskId taskId, - uint64 id, - const FileLoadTo &to, - const TextWithTags &caption, - bool spoiler, - std::shared_ptr album); +using UploadFileParts = QMap; +struct FilePrepareDescriptor { + TaskId taskId = kEmptyTaskId; + base::required id; + SendMediaType type = SendMediaType::File; + FileLoadTo to = { PeerId(), Api::SendOptions(), FullReplyTo(), MsgId() }; + TextWithTags caption; + bool spoiler = false; + std::shared_ptr album; +}; +struct FilePrepareResult { + explicit FilePrepareResult(FilePrepareDescriptor &&descriptor); - TaskId taskId; - uint64 id; + TaskId taskId = kEmptyTaskId; + uint64 id = 0; FileLoadTo to; std::shared_ptr album; SendMediaType type = SendMediaType::File; @@ -216,8 +185,8 @@ struct FileLoadResult { QImage goodThumbnail; QByteArray goodThumbnailBytes; - MTPPhoto photo; - MTPDocument document; + MTPPhoto photo = MTP_photoEmpty(MTP_long(0)); + MTPDocument document = MTP_documentEmpty(MTP_long(0)); PreparedPhotoThumbs photoThumbs; TextWithTags caption; @@ -230,6 +199,9 @@ struct FileLoadResult { }; +[[nodiscard]] std::shared_ptr MakePreparedFile( + FilePrepareDescriptor &&descriptor); + class FileLoadTask final : public Task { public: static std::unique_ptr ReadMediaInformation( @@ -276,7 +248,7 @@ public: } void finish() override; - FileLoadResult *peekResult() const; + FilePrepareResult *peekResult() const; private: static bool CheckForSong( @@ -312,6 +284,6 @@ private: TextWithTags _caption; bool _spoiler = false; - std::shared_ptr _result; + std::shared_ptr _result; }; diff --git a/Telegram/SourceFiles/window/themes/window_theme.cpp b/Telegram/SourceFiles/window/themes/window_theme.cpp index 7409a95ee..b225b321e 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme.cpp @@ -585,11 +585,11 @@ void ChatBackground::checkUploadWallPaper() { } const auto ready = PrepareWallPaper(_session->mainDcId(), _original); - const auto documentId = ready.id; + const auto documentId = ready->id; _wallPaperUploadId = FullMsgId( _session->userPeerId(), _session->data().nextLocalMessageId()); - _session->uploader().uploadMedia(_wallPaperUploadId, ready); + _session->uploader().upload(_wallPaperUploadId, ready); if (_wallPaperUploadLifetime) { return; } @@ -1529,7 +1529,9 @@ bool ReadPaletteValues(const QByteArray &content, Fn PrepareWallPaper( + MTP::DcId dcId, + const QImage &image) { PreparedPhotoThumbs thumbnails; QVector sizes; @@ -1555,6 +1557,7 @@ SendMediaReady PrepareWallPaper(MTP::DcId dcId, const QImage &image) { }; push("s", scaled(320)); + const auto id = base::RandomValue(); const auto filename = u"wallpaper.jpg"_q; auto attributes = QVector( 1, @@ -1562,8 +1565,20 @@ SendMediaReady PrepareWallPaper(MTP::DcId dcId, const QImage &image) { attributes.push_back(MTP_documentAttributeImageSize( MTP_int(image.width()), MTP_int(image.height()))); - const auto id = base::RandomValue(); - const auto document = MTP_document( + + auto result = MakePreparedFile({ + .id = id, + .type = SendMediaType::ThemeFile, + }); + result->filename = filename; + result->content = jpeg; + result->filesize = jpeg.size(); + result->setFileData(jpeg); + if (thumbnails.empty()) { + result->thumb = thumbnails.front().second.image; + result->thumbbytes = thumbnails.front().second.bytes; + } + result->document = MTP_document( MTP_flags(0), MTP_long(id), MTP_long(0), @@ -1575,21 +1590,7 @@ SendMediaReady PrepareWallPaper(MTP::DcId dcId, const QImage &image) { MTPVector(), MTP_int(dcId), MTP_vector(attributes)); - - return SendMediaReady( - SendMediaType::ThemeFile, - QString(), // filepath - filename, - jpeg.size(), - jpeg, - id, - 0, - QString(), - PeerId(), - MTP_photoEmpty(MTP_long(0)), - thumbnails, - document, - QByteArray()); + return result; } std::unique_ptr DefaultChatThemeOn(rpl::lifetime &lifetime) { diff --git a/Telegram/SourceFiles/window/themes/window_theme.h b/Telegram/SourceFiles/window/themes/window_theme.h index 1425e4d07..b0497fb0c 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.h +++ b/Telegram/SourceFiles/window/themes/window_theme.h @@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/style/style_core_palette.h" class QFileSystemWatcher; -struct SendMediaReady; +struct FilePrepareResult; namespace style { struct colorizer; @@ -298,7 +298,7 @@ private: }; -[[nodiscard]] SendMediaReady PrepareWallPaper( +[[nodiscard]] std::shared_ptr PrepareWallPaper( MTP::DcId dcId, const QImage &image); diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp index d448ca185..c430b3e28 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp @@ -385,7 +385,7 @@ bool CopyColorsToPalette( }); } -SendMediaReady PrepareThemeMedia( +std::shared_ptr PrepareThemeMedia( MTP::DcId dcId, const QString &name, const QByteArray &content) { @@ -403,28 +403,29 @@ SendMediaReady PrepareThemeMedia( thumbnail.save(&buffer, "JPG", 87); } - const auto push = [&]( - const char *type, - QImage &&image, - QByteArray bytes = QByteArray()) { - sizes.push_back(MTP_photoSize( - MTP_string(type), - MTP_int(image.width()), - MTP_int(image.height()), MTP_int(0))); - thumbnails.emplace(type[0], PreparedPhotoThumb{ - .image = std::move(image), - .bytes = std::move(bytes) - }); - }; - push("s", std::move(thumbnail), thumbnailBytes); + sizes.push_back(MTP_photoSize( + MTP_string("s"), + MTP_int(thumbnail.width()), + MTP_int(thumbnail.height()), MTP_int(0))); + const auto id = base::RandomValue(); const auto filename = base::FileNameFromUserString(name) + u".tdesktop-theme"_q; auto attributes = QVector( 1, MTP_documentAttributeFilename(MTP_string(filename))); - const auto id = base::RandomValue(); - const auto document = MTP_document( + + auto result = MakePreparedFile({ + .id = id, + .type = SendMediaType::ThemeFile, + }); + result->filename = filename; + result->content = content; + result->filesize = content.size(); + result->thumb = thumbnail; + result->thumbname = "thumb.jpg"; + result->setThumbData(thumbnailBytes); + result->document = MTP_document( MTP_flags(0), MTP_long(id), MTP_long(0), @@ -436,21 +437,7 @@ SendMediaReady PrepareThemeMedia( MTPVector(), MTP_int(dcId), MTP_vector(attributes)); - - return SendMediaReady( - SendMediaType::ThemeFile, - QString(), // filepath - filename, - content.size(), - content, - id, - 0, - QString(), - PeerId(), - MTP_photoEmpty(MTP_long(0)), - thumbnails, - document, - thumbnailBytes); + return result; } Fn SavePreparedTheme( @@ -570,7 +557,7 @@ Fn SavePreparedTheme( session->mainDcId(), fields.title, theme); - state->filename = media.filename; + state->filename = media->filename; state->themeContent = theme; session->uploader().documentReady( @@ -580,7 +567,7 @@ Fn SavePreparedTheme( uploadTheme(data); }, state->lifetime); - session->uploader().uploadMedia(state->id, media); + session->uploader().upload(state->id, media); }; const auto save = [=] { @@ -999,12 +986,15 @@ ParsedTheme ParseTheme( [[nodiscard]] QString GenerateSlug() { const auto letters = uint8('Z' + 1 - 'A'); const auto digits = uint8('9' + 1 - '0'); + const auto firstValues = uint8(2 * letters); const auto values = uint8(2 * letters + digits); auto result = QString(); result.reserve(kRandomSlugSize); for (auto i = 0; i != kRandomSlugSize; ++i) { - const auto value = base::RandomValue() % values; + const auto value = i + ? (base::RandomValue() % values) + : (base::RandomValue() % firstValues); if (value < letters) { result.append(char('A' + value)); } else if (value < 2 * letters) {