Added initial support of api for fallback photo.

This commit is contained in:
23rd 2022-12-19 18:54:05 +03:00 committed by John Preston
parent b135a09e00
commit 721b2ebe8a
2 changed files with 63 additions and 22 deletions

View file

@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_photo.h" #include "data/data_photo.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_user_photos.h"
#include "history/history.h" #include "history/history.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "storage/file_upload.h" #include "storage/file_upload.h"
@ -113,7 +114,11 @@ PeerPhoto::PeerPhoto(not_null<ApiWrap*> api)
} }
void PeerPhoto::upload(not_null<PeerData*> peer, QImage &&image) { void PeerPhoto::upload(not_null<PeerData*> peer, QImage &&image) {
upload(peer, std::move(image), false); upload(peer, std::move(image), UploadType::Default);
}
void PeerPhoto::uploadFallback(not_null<PeerData*> peer, QImage &&image) {
upload(peer, std::move(image), UploadType::Fallback);
} }
void PeerPhoto::updateSelf(not_null<PhotoData*> photo) { void PeerPhoto::updateSelf(not_null<PhotoData*> photo) {
@ -131,7 +136,7 @@ void PeerPhoto::updateSelf(not_null<PhotoData*> photo) {
void PeerPhoto::upload( void PeerPhoto::upload(
not_null<PeerData*> peer, not_null<PeerData*> peer,
QImage &&image, QImage &&image,
bool suggestion) { UploadType type) {
peer = peer->migrateToOrMe(); peer = peer->migrateToOrMe();
const auto ready = PreparePeerPhoto( const auto ready = PreparePeerPhoto(
_api.instance().mainDcId(), _api.instance().mainDcId(),
@ -144,21 +149,23 @@ void PeerPhoto::upload(
const auto already = ranges::find( const auto already = ranges::find(
_uploads, _uploads,
peer, peer,
[](const auto &pair) { return pair.second; }); [](const auto &pair) { return pair.second.peer; });
if (already != end(_uploads)) { if (already != end(_uploads)) {
_session->uploader().cancel(already->first); _session->uploader().cancel(already->first);
_suggestions.remove(already->first); _suggestions.remove(already->first);
_uploads.erase(already); _uploads.erase(already);
} }
_uploads.emplace(fakeId, peer); _uploads.emplace(
if (suggestion) { fakeId,
UploadValue{ peer, type == UploadType::Fallback });
if (type == UploadType::Suggestion) {
_suggestions.emplace(fakeId); _suggestions.emplace(fakeId);
} }
_session->uploader().uploadMedia(fakeId, ready); _session->uploader().uploadMedia(fakeId, ready);
} }
void PeerPhoto::suggest(not_null<PeerData*> peer, QImage &&image) { void PeerPhoto::suggest(not_null<PeerData*> peer, QImage &&image) {
upload(peer, std::move(image), true); upload(peer, std::move(image), UploadType::Suggestion);
} }
void PeerPhoto::clear(not_null<PhotoData*> photo) { void PeerPhoto::clear(not_null<PhotoData*> photo) {
@ -186,12 +193,23 @@ void PeerPhoto::clear(not_null<PhotoData*> photo) {
)).done(applier).send(); )).done(applier).send();
} }
} else { } else {
_api.request(MTPphotos_DeletePhotos( const auto fallbackPhotoId = SyncUserFallbackPhotoViewer(self);
MTP_vector<MTPInputPhoto>(1, photo->mtpInput()) if (fallbackPhotoId && (*fallbackPhotoId) == photo->id) {
)).send(); _api.request(MTPphotos_UpdateProfilePhoto(
_session->storage().remove(Storage::UserPhotosRemoveOne( MTP_flags(MTPphotos_UpdateProfilePhoto::Flag::f_fallback),
peerToUser(self->id), MTP_inputPhotoEmpty()
photo->id)); )).send();
_session->storage().add(Storage::UserPhotosSetBack(
peerToUser(self->id),
PhotoId()));
} else {
_api.request(MTPphotos_DeletePhotos(
MTP_vector<MTPInputPhoto>(1, photo->mtpInput())
)).send();
_session->storage().remove(Storage::UserPhotosRemoveOne(
peerToUser(self->id),
photo->id));
}
} }
} }
@ -249,27 +267,35 @@ void PeerPhoto::set(not_null<PeerData*> peer, not_null<PhotoData*> photo) {
} }
void PeerPhoto::ready(const FullMsgId &msgId, const MTPInputFile &file) { void PeerPhoto::ready(const FullMsgId &msgId, const MTPInputFile &file) {
const auto maybePeer = _uploads.take(msgId); const auto maybeUploadValue = _uploads.take(msgId);
const auto suggestion = _suggestions.contains(msgId); const auto suggestion = _suggestions.contains(msgId);
_suggestions.remove(msgId); _suggestions.remove(msgId);
if (!maybePeer) { if (!maybeUploadValue) {
return; return;
} }
const auto peer = *maybePeer; const auto peer = maybeUploadValue->peer;
const auto fallback = maybeUploadValue->fallback;
const auto applier = [=](const MTPUpdates &result) { const auto applier = [=](const MTPUpdates &result) {
_session->updates().applyUpdates(result); _session->updates().applyUpdates(result);
}; };
if (peer->isSelf()) { if (peer->isSelf()) {
_api.request(MTPphotos_UploadProfilePhoto( _api.request(MTPphotos_UploadProfilePhoto(
MTP_flags(MTPphotos_UploadProfilePhoto::Flag::f_file), MTP_flags(MTPphotos_UploadProfilePhoto::Flag::f_file
| (fallback
? MTPphotos_UploadProfilePhoto::Flag::f_fallback
: MTPphotos_UploadProfilePhoto::Flags(0))),
file, file,
MTPInputFile(), // video MTPInputFile(), // video
MTPdouble() // video_start_ts MTPdouble() // video_start_ts
)).done([=](const MTPphotos_Photo &result) { )).done([=](const MTPphotos_Photo &result) {
result.match([&](const MTPDphotos_photo &data) { const auto photoId = _session->data().processPhoto(
_session->data().processPhoto(data.vphoto()); result.data().vphoto())->id;
_session->data().processUsers(data.vusers()); _session->data().processUsers(result.data().vusers());
}); if (fallback) {
_session->storage().add(Storage::UserPhotosSetBack(
peerToUser(peer->id),
photoId));
}
}).send(); }).send();
} else if (const auto chat = peer->asChat()) { } else if (const auto chat = peer->asChat()) {
const auto history = _session->data().history(chat); const auto history = _session->data().history(chat);

View file

@ -25,6 +25,7 @@ public:
explicit PeerPhoto(not_null<ApiWrap*> api); explicit PeerPhoto(not_null<ApiWrap*> api);
void upload(not_null<PeerData*> peer, QImage &&image); void upload(not_null<PeerData*> peer, QImage &&image);
void uploadFallback(not_null<PeerData*> peer, QImage &&image);
void updateSelf(not_null<PhotoData*> photo); void updateSelf(not_null<PhotoData*> photo);
void suggest(not_null<PeerData*> peer, QImage &&image); void suggest(not_null<PeerData*> peer, QImage &&image);
void clear(not_null<PhotoData*> photo); void clear(not_null<PhotoData*> photo);
@ -42,13 +43,27 @@ public:
not_null<UserData*> user) const; not_null<UserData*> user) const;
private: private:
enum class UploadType {
Default,
Suggestion,
Fallback,
};
void ready(const FullMsgId &msgId, const MTPInputFile &file); void ready(const FullMsgId &msgId, const MTPInputFile &file);
void upload(not_null<PeerData*> peer, QImage &&image, bool suggestion); void upload(
not_null<PeerData*> peer,
QImage &&image,
UploadType type);
const not_null<Main::Session*> _session; const not_null<Main::Session*> _session;
MTP::Sender _api; MTP::Sender _api;
base::flat_map<FullMsgId, not_null<PeerData*>> _uploads; struct UploadValue {
not_null<PeerData*> peer;
bool fallback = false;
};
base::flat_map<FullMsgId, UploadValue> _uploads;
base::flat_set<FullMsgId> _suggestions; base::flat_set<FullMsgId> _suggestions;
base::flat_map<not_null<UserData*>, mtpRequestId> _userPhotosRequests; base::flat_map<not_null<UserData*>, mtpRequestId> _userPhotosRequests;