mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 07:07:08 +02:00
Added api support to upload emoji markup of userpic instead of image.
This commit is contained in:
parent
d6bf5513ff
commit
9940ee21d3
12 changed files with 127 additions and 45 deletions
Telegram/SourceFiles
api
boxes
history/view/media
info/profile
intro
settings
ui/controls
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -215,7 +215,7 @@ void Controller::initNameFields(
|
|||
} else {
|
||||
user->session().api().peerPhoto().upload(
|
||||
user,
|
||||
base::duplicate(*personal));
|
||||
{ base::duplicate(*personal) });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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>(
|
||||
|
|
|
@ -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([=] {
|
||||
|
|
|
@ -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) });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -83,6 +83,10 @@ public:
|
|||
struct ChosenImage {
|
||||
QImage image;
|
||||
ChosenType type = ChosenType::Set;
|
||||
struct {
|
||||
DocumentId documentId = 0;
|
||||
std::vector<QColor> colors;
|
||||
} markup;
|
||||
};
|
||||
|
||||
// Role::OpenPhoto
|
||||
|
|
Loading…
Add table
Reference in a new issue