1 /* 2 This file is part of Telegram Desktop, 3 the official desktop application for the Telegram messaging service. 4 5 For license and copyright information please follow this link: 6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL 7 */ 8 #pragma once 9 10 #include "api/api_common.h" 11 #include "base/timer.h" 12 #include "mtproto/facade.h" 13 14 class ApiWrap; 15 struct FileLoadResult; 16 struct SendMediaReady; 17 18 namespace Api { 19 enum class SendProgressType; 20 } // namespace Api 21 22 namespace Main { 23 class Session; 24 } // namespace Main 25 26 namespace Storage { 27 28 // MTP big files methods used for files greater than 10mb. 29 constexpr auto kUseBigFilesFrom = 10 * 1024 * 1024; 30 31 struct UploadedPhoto { 32 FullMsgId fullId; 33 Api::SendOptions options; 34 MTPInputFile file; 35 bool edit = false; 36 std::vector<MTPInputDocument> attachedStickers; 37 }; 38 39 struct UploadedDocument { 40 FullMsgId fullId; 41 Api::SendOptions options; 42 MTPInputFile file; 43 std::optional<MTPInputFile> thumb; 44 bool edit = false; 45 std::vector<MTPInputDocument> attachedStickers; 46 }; 47 48 struct UploadSecureProgress { 49 FullMsgId fullId; 50 int offset = 0; 51 int size = 0; 52 }; 53 54 struct UploadSecureDone { 55 FullMsgId fullId; 56 uint64 fileId = 0; 57 int partsCount = 0; 58 }; 59 60 class Uploader final : public QObject { 61 public: 62 explicit Uploader(not_null<ApiWrap*> api); 63 ~Uploader(); 64 65 [[nodiscard]] Main::Session &session() const; 66 67 void uploadMedia(const FullMsgId &msgId, const SendMediaReady &image); 68 void upload( 69 const FullMsgId &msgId, 70 const std::shared_ptr<FileLoadResult> &file); 71 72 void cancel(const FullMsgId &msgId); 73 void pause(const FullMsgId &msgId); 74 void confirm(const FullMsgId &msgId); 75 76 void clear(); 77 photoReady()78 rpl::producer<UploadedPhoto> photoReady() const { 79 return _photoReady.events(); 80 } documentReady()81 rpl::producer<UploadedDocument> documentReady() const { 82 return _documentReady.events(); 83 } secureReady()84 rpl::producer<UploadSecureDone> secureReady() const { 85 return _secureReady.events(); 86 } photoProgress()87 rpl::producer<FullMsgId> photoProgress() const { 88 return _photoProgress.events(); 89 } documentProgress()90 rpl::producer<FullMsgId> documentProgress() const { 91 return _documentProgress.events(); 92 } secureProgress()93 rpl::producer<UploadSecureProgress> secureProgress() const { 94 return _secureProgress.events(); 95 } photoFailed()96 rpl::producer<FullMsgId> photoFailed() const { 97 return _photoFailed.events(); 98 } documentFailed()99 rpl::producer<FullMsgId> documentFailed() const { 100 return _documentFailed.events(); 101 } secureFailed()102 rpl::producer<FullMsgId> secureFailed() const { 103 return _secureFailed.events(); 104 } 105 106 void unpause(); 107 void sendNext(); 108 void stopSessions(); 109 110 private: 111 struct File; 112 113 void partLoaded(const MTPBool &result, mtpRequestId requestId); 114 void partFailed(const MTP::Error &error, mtpRequestId requestId); 115 116 void processPhotoProgress(const FullMsgId &msgId); 117 void processPhotoFailed(const FullMsgId &msgId); 118 void processDocumentProgress(const FullMsgId &msgId); 119 void processDocumentFailed(const FullMsgId &msgId); 120 121 void currentFailed(); 122 123 void sendProgressUpdate( 124 not_null<HistoryItem*> item, 125 Api::SendProgressType type, 126 int progress = 0); 127 128 const not_null<ApiWrap*> _api; 129 base::flat_map<mtpRequestId, QByteArray> requestsSent; 130 base::flat_map<mtpRequestId, int32> docRequestsSent; 131 base::flat_map<mtpRequestId, int32> dcMap; 132 uint32 sentSize = 0; 133 uint32 sentSizes[MTP::kUploadSessionsCount] = { 0 }; 134 135 FullMsgId uploadingId; 136 FullMsgId _pausedId; 137 std::map<FullMsgId, File> queue; 138 std::map<FullMsgId, File> uploaded; 139 base::Timer _nextTimer, _stopSessionsTimer; 140 141 rpl::event_stream<UploadedPhoto> _photoReady; 142 rpl::event_stream<UploadedDocument> _documentReady; 143 rpl::event_stream<UploadSecureDone> _secureReady; 144 rpl::event_stream<FullMsgId> _photoProgress; 145 rpl::event_stream<FullMsgId> _documentProgress; 146 rpl::event_stream<UploadSecureProgress> _secureProgress; 147 rpl::event_stream<FullMsgId> _photoFailed; 148 rpl::event_stream<FullMsgId> _documentFailed; 149 rpl::event_stream<FullMsgId> _secureFailed; 150 151 rpl::lifetime _lifetime; 152 153 }; 154 155 } // namespace Storage 156