Added api support to upload emoji markup of userpic instead of image.

This commit is contained in:
23rd 2023-01-30 23:02:02 +03:00 committed by John Preston
parent d6bf5513ff
commit 9940ee21d3
12 changed files with 127 additions and 45 deletions

View File

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unixtime.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_document.h"
#include "data/data_file_origin.h"
#include "data/data_peer.h"
#include "data/data_photo.h"
@ -32,7 +33,7 @@ namespace {
constexpr auto kSharedMediaLimit = 100;
SendMediaReady PreparePeerPhoto(
[[nodiscard]] SendMediaReady PreparePeerPhoto(
MTP::DcId dcId,
PeerId peerId,
QImage &&image) {
@ -99,6 +100,53 @@ SendMediaReady PreparePeerPhoto(
0);
}
[[nodiscard]] std::optional<MTPVideoSize> PrepareMtpMarkup(
not_null<Main::Session*> session,
const PeerPhoto::UserPhoto &d) {
const auto &documentId = d.markupDocumentId;
const auto &colors = d.markupColors;
if (!documentId || colors.empty()) {
return std::nullopt;
}
const auto document = session->data().document(documentId);
if (const auto sticker = document->sticker()) {
if (sticker->isStatic()) {
return std::nullopt;
}
const auto serializeColor = [](const QColor &color) {
return (quint32(std::clamp(color.red(), 0, 255)) << 16)
| (quint32(std::clamp(color.green(), 0, 255)) << 8)
| quint32(std::clamp(color.blue(), 0, 255));
};
auto mtpColors = QVector<MTPint>();
mtpColors.reserve(colors.size());
ranges::transform(
colors,
ranges::back_inserter(mtpColors),
[&](const QColor &c) { return MTP_int(serializeColor(c)); });
if (sticker->set.id && sticker->set.accessHash) {
return MTP_videoSizeStickerMarkup(
MTP_inputStickerSetID(
MTP_long(sticker->set.id),
MTP_long(sticker->set.accessHash)),
MTP_long(document->id),
MTP_vector(mtpColors));
} else if (!sticker->set.shortName.isEmpty()) {
return MTP_videoSizeStickerMarkup(
MTP_inputStickerSetShortName(
MTP_string(sticker->set.shortName)),
MTP_long(document->id),
MTP_vector(mtpColors));
} else {
return MTP_videoSizeEmojiMarkup(
MTP_long(document->id),
MTP_vector(mtpColors));
}
}
return std::nullopt;
}
} // namespace
PeerPhoto::PeerPhoto(not_null<ApiWrap*> api)
@ -109,20 +157,20 @@ PeerPhoto::PeerPhoto(not_null<ApiWrap*> api)
// only queued, because it is not constructed yet.
_session->uploader().photoReady(
) | rpl::start_with_next([=](const Storage::UploadedMedia &data) {
ready(data.fullId, data.info.file);
ready(data.fullId, data.info.file, std::nullopt);
}, _session->lifetime());
});
}
void PeerPhoto::upload(
not_null<PeerData*> peer,
QImage &&image,
UserPhoto &&photo,
Fn<void()> done) {
upload(peer, std::move(image), UploadType::Default, std::move(done));
upload(peer, std::move(photo), UploadType::Default, std::move(done));
}
void PeerPhoto::uploadFallback(not_null<PeerData*> peer, QImage &&image) {
upload(peer, std::move(image), UploadType::Fallback, nullptr);
void PeerPhoto::uploadFallback(not_null<PeerData*> peer, UserPhoto &&photo) {
upload(peer, std::move(photo), UploadType::Fallback, nullptr);
}
void PeerPhoto::updateSelf(
@ -159,14 +207,11 @@ void PeerPhoto::updateSelf(
void PeerPhoto::upload(
not_null<PeerData*> peer,
QImage &&image,
UserPhoto &&photo,
UploadType type,
Fn<void()> done) {
peer = peer->migrateToOrMe();
const auto ready = PreparePeerPhoto(
_api.instance().mainDcId(),
peer->id,
std::move(image));
const auto mtpMarkup = PrepareMtpMarkup(_session, photo);
const auto fakeId = FullMsgId(
peer->id,
@ -182,11 +227,19 @@ void PeerPhoto::upload(
_uploads.emplace(
fakeId,
UploadValue{ peer, type, std::move(done) });
_session->uploader().uploadMedia(fakeId, ready);
if (mtpMarkup) {
ready(fakeId, std::nullopt, mtpMarkup);
} else {
const auto ready = PreparePeerPhoto(
_api.instance().mainDcId(),
peer->id,
base::take(photo.image));
_session->uploader().uploadMedia(fakeId, ready);
}
}
void PeerPhoto::suggest(not_null<PeerData*> peer, QImage &&image) {
upload(peer, std::move(image), UploadType::Suggestion, nullptr);
void PeerPhoto::suggest(not_null<PeerData*> peer, UserPhoto &&photo) {
upload(peer, std::move(photo), UploadType::Suggestion, nullptr);
}
void PeerPhoto::clear(not_null<PhotoData*> photo) {
@ -287,7 +340,10 @@ 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,
std::optional<MTPInputFile> file,
std::optional<MTPVideoSize> videoSize) {
const auto maybeUploadValue = _uploads.take(msgId);
if (!maybeUploadValue) {
return;
@ -302,15 +358,16 @@ void PeerPhoto::ready(const FullMsgId &msgId, const MTPInputFile &file) {
}
};
if (peer->isSelf()) {
using Flag = MTPphotos_UploadProfilePhoto::Flag;
const auto none = MTPphotos_UploadProfilePhoto::Flags(0);
_api.request(MTPphotos_UploadProfilePhoto(
MTP_flags(MTPphotos_UploadProfilePhoto::Flag::f_file
| ((type == UploadType::Fallback)
? MTPphotos_UploadProfilePhoto::Flag::f_fallback
: MTPphotos_UploadProfilePhoto::Flags(0))),
file,
MTP_flags((file ? Flag::f_file : none)
| (videoSize ? Flag::f_video_emoji_markup : none)
| ((type == UploadType::Fallback) ? Flag::f_fallback : none)),
file ? (*file) : MTPInputFile(),
MTPInputFile(), // video
MTPdouble(), // video_start_ts
MTPVideoSize() // video_emoji_markup
videoSize ? (*videoSize) : MTPVideoSize() // video_emoji_markup
)).done([=](const MTPphotos_Photo &result) {
const auto photoId = _session->data().processPhoto(
result.data().vphoto())->id;
@ -326,25 +383,31 @@ void PeerPhoto::ready(const FullMsgId &msgId, const MTPInputFile &file) {
}).send();
} else if (const auto chat = peer->asChat()) {
const auto history = _session->data().history(chat);
using Flag = MTPDinputChatUploadedPhoto::Flag;
const auto none = MTPDinputChatUploadedPhoto::Flags(0);
history->sendRequestId = _api.request(MTPmessages_EditChatPhoto(
chat->inputChat,
MTP_inputChatUploadedPhoto(
MTP_flags(MTPDinputChatUploadedPhoto::Flag::f_file),
file,
MTP_flags((file ? Flag::f_file : none)
| (videoSize ? Flag::f_video_emoji_markup : none)),
file ? (*file) : MTPInputFile(),
MTPInputFile(), // video
MTPdouble(), // video_start_ts
MTPVideoSize()) // video_emoji_markup
videoSize ? (*videoSize) : MTPVideoSize()) // video_emoji_markup
)).done(applier).afterRequest(history->sendRequestId).send();
} else if (const auto channel = peer->asChannel()) {
using Flag = MTPDinputChatUploadedPhoto::Flag;
const auto none = MTPDinputChatUploadedPhoto::Flags(0);
const auto history = _session->data().history(channel);
history->sendRequestId = _api.request(MTPchannels_EditPhoto(
channel->inputChannel,
MTP_inputChatUploadedPhoto(
MTP_flags(MTPDinputChatUploadedPhoto::Flag::f_file),
file,
MTP_flags((file ? Flag::f_file : none)
| (videoSize ? Flag::f_video_emoji_markup : none)),
file ? (*file) : MTPInputFile(),
MTPInputFile(), // video
MTPdouble(), // video_start_ts
MTPVideoSize()) // video_emoji_markup
videoSize ? (*videoSize) : MTPVideoSize()) // video_emoji_markup
)).done(applier).afterRequest(history->sendRequestId).send();
} else if (const auto user = peer->asUser()) {
using Flag = MTPphotos_UploadContactProfilePhoto::Flag;
@ -354,7 +417,7 @@ void PeerPhoto::ready(const FullMsgId &msgId, const MTPInputFile &file) {
? Flag::f_suggest
: Flag::f_save)),
user->inputUser,
file,
*file,
MTPInputFile(), // video
MTPdouble() // video_start_ts
)).done([=](const MTPphotos_Photo &result) {

View File

@ -33,16 +33,22 @@ public:
Group,
};
struct UserPhoto {
QImage image;
DocumentId markupDocumentId = 0;
std::vector<QColor> markupColors;
};
void upload(
not_null<PeerData*> peer,
QImage &&image,
UserPhoto &&photo,
Fn<void()> done = nullptr);
void uploadFallback(not_null<PeerData*> peer, QImage &&image);
void uploadFallback(not_null<PeerData*> peer, UserPhoto &&photo);
void updateSelf(
not_null<PhotoData*> photo,
Data::FileOrigin origin,
Fn<void()> done = nullptr);
void suggest(not_null<PeerData*> peer, QImage &&image);
void suggest(not_null<PeerData*> peer, UserPhoto &&photo);
void clear(not_null<PhotoData*> photo);
void clearPersonal(not_null<UserData*> user);
void set(not_null<PeerData*> peer, not_null<PhotoData*> photo);
@ -68,10 +74,13 @@ private:
Fallback,
};
void ready(const FullMsgId &msgId, const MTPInputFile &file);
void ready(
const FullMsgId &msgId,
std::optional<MTPInputFile> file,
std::optional<MTPVideoSize> videoSize);
void upload(
not_null<PeerData*> peer,
QImage &&image,
UserPhoto &&photo,
UploadType type,
Fn<void()> done);

View File

@ -104,7 +104,7 @@ void ChatCreateDone(
if (!image.isNull()) {
chat->session().api().peerPhoto().upload(
chat,
std::move(image));
{ std::move(image) });
}
if (ttlPeriod) {
chat->setMessagesTTL(ttlPeriod);
@ -828,7 +828,7 @@ void GroupInfoBox::createChannel(
if (!image.isNull()) {
channel->session().api().peerPhoto().upload(
channel,
std::move(image));
{ std::move(image) });
}
if (_ttlPeriod && channel->isMegagroup()) {
channel->setMessagesTTL(_ttlPeriod);

View File

@ -215,7 +215,7 @@ void Controller::initNameFields(
} else {
user->session().api().peerPhoto().upload(
user,
base::duplicate(*personal));
{ base::duplicate(*personal) });
}
}
};

View File

@ -1879,7 +1879,9 @@ void Controller::savePhoto() {
? _controls.photo->takeResultImage()
: QImage();
if (!image.isNull()) {
_peer->session().api().peerPhoto().upload(_peer, std::move(image));
_peer->session().api().peerPhoto().upload(
_peer,
{ std::move(image) });
}
_box->closeBox();
}

View File

@ -79,7 +79,7 @@ void ShowUserpicSuggestion(
&& original->constBits() == image.constBits()) {
peerPhotos.updateSelf(photo, itemId, setDone);
} else {
peerPhotos.upload(user, std::move(image), setDone);
peerPhotos.upload(user, { std::move(image) }, setDone);
}
};
using namespace Editor;

View File

@ -449,12 +449,12 @@ void Cover::refreshUploadPhotoOverlay() {
_userpic->showCustom(base::duplicate(image));
_peer->session().api().peerPhoto().upload(
_peer,
std::move(image));
{ std::move(image) });
break;
case ChosenType::Suggest:
_peer->session().api().peerPhoto().suggest(
_peer,
std::move(image));
{ std::move(image) });
break;
}
});
@ -478,7 +478,7 @@ void Cover::setupChangePersonal() {
if (chosen.type == Ui::UserpicButton::ChosenType::Suggest) {
_peer->session().api().peerPhoto().suggest(
_peer,
std::move(chosen.image));
{ std::move(chosen.image) });
} else {
_personalChosen = std::move(chosen.image);
_userpic->showCustom(base::duplicate(*_personalChosen));

View File

@ -226,7 +226,9 @@ void Step::createSession(
session.saveSettingsDelayed();
}
if (!photo.isNull()) {
session.api().peerPhoto().upload(session.user(), std::move(photo));
session.api().peerPhoto().upload(
session.user(),
{ std::move(photo) });
}
account->appConfig().refresh();
if (session.supportMode()) {

View File

@ -256,7 +256,7 @@ void SetupPhoto(
auto &image = chosen.image;
UpdatePhotoLocally(self, image);
photo->showCustom(base::duplicate(image));
self->session().api().peerPhoto().upload(self, std::move(image));
self->session().api().peerPhoto().upload(self, { std::move(image) });
}, upload->lifetime());
const auto name = Ui::CreateChild<Ui::FlatLabel>(

View File

@ -144,7 +144,9 @@ Cover::Cover(
Ui::UserpicButton::ChosenImage chosen) {
auto &image = chosen.image;
_userpic->showCustom(base::duplicate(image));
_user->session().api().peerPhoto().upload(_user, std::move(image));
_user->session().api().peerPhoto().upload(
_user,
{ std::move(image) });
});
_badge.setPremiumClickCallback([=] {

View File

@ -1171,7 +1171,7 @@ object_ptr<Ui::RpWidget> ProfilePhotoPrivacyController::setupBelowWidget(
} else if (!state->localOriginal.isNull()) {
controller->session().api().peerPhoto().uploadFallback(
self,
base::take(state->localOriginal));
{ base::take(state->localOriginal) });
}
};

View File

@ -83,6 +83,10 @@ public:
struct ChosenImage {
QImage image;
ChosenType type = ChosenType::Set;
struct {
DocumentId documentId = 0;
std::vector<QColor> colors;
} markup;
};
// Role::OpenPhoto