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