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