Use Data::MediaPreload in sponsored messages.

This commit is contained in:
John Preston 2024-10-02 11:45:33 +04:00
parent 677314dacb
commit d3df2dc1e5
2 changed files with 53 additions and 48 deletions

View file

@ -12,10 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "data/data_channel.h" #include "data/data_channel.h"
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_document_media.h"
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
#include "data/data_media_preload.h"
#include "data/data_photo.h" #include "data/data_photo.h"
#include "data/data_photo_media.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "history/history.h" #include "history/history.h"
@ -91,21 +90,7 @@ SponsoredMessages::AppendResult SponsoredMessages::append(
if (entryIt == end(list.entries)) { if (entryIt == end(list.entries)) {
list.showedAll = true; list.showedAll = true;
return SponsoredMessages::AppendResult::None; return SponsoredMessages::AppendResult::None;
} } else if (entryIt->preload) {
if (const auto media = entryIt->documentMedia) {
const auto fullDuration = media->owner()->duration();
if (fullDuration <= 0) {
if (!media->loaded()) {
return SponsoredMessages::AppendResult::MediaLoading;
}
} else {
constexpr auto kEnoughDuration = float64(2000);
if ((kEnoughDuration / fullDuration) > media->progress()) {
return SponsoredMessages::AppendResult::MediaLoading;
}
}
}
if (entryIt->photoMedia && !entryIt->photoMedia->loaded()) {
return SponsoredMessages::AppendResult::MediaLoading; return SponsoredMessages::AppendResult::MediaLoading;
} }
entryIt->item.reset(history->addSponsoredMessage( entryIt->item.reset(history->addSponsoredMessage(
@ -284,15 +269,14 @@ void SponsoredMessages::append(
const MTPSponsoredMessage &message) { const MTPSponsoredMessage &message) {
const auto &data = message.data(); const auto &data = message.data();
const auto randomId = data.vrandom_id().v; const auto randomId = data.vrandom_id().v;
auto mediaPhoto = std::shared_ptr<Data::PhotoMedia>(nullptr); auto mediaPhoto = (PhotoData*)nullptr;
auto mediaDocument = std::shared_ptr<Data::DocumentMedia>(nullptr); auto mediaDocument = (DocumentData*)nullptr;
{ {
if (data.vmedia()) { if (data.vmedia()) {
data.vmedia()->match([&](const MTPDmessageMediaPhoto &media) { data.vmedia()->match([&](const MTPDmessageMediaPhoto &media) {
if (const auto tlPhoto = media.vphoto()) { if (const auto tlPhoto = media.vphoto()) {
tlPhoto->match([&](const MTPDphoto &data) { tlPhoto->match([&](const MTPDphoto &data) {
const auto p = history->owner().processPhoto(data); mediaPhoto = history->owner().processPhoto(data);
mediaPhoto = p->createMediaView();
}, [](const MTPDphotoEmpty &) { }, [](const MTPDphotoEmpty &) {
}); });
} }
@ -304,7 +288,7 @@ void SponsoredMessages::append(
|| d->isSilentVideo() || d->isSilentVideo()
|| d->isAnimation() || d->isAnimation()
|| d->isGifv()) { || d->isGifv()) {
mediaDocument = d->createMediaView(); mediaDocument = d;
} }
}, [](const MTPDdocumentEmpty &) { }, [](const MTPDdocumentEmpty &) {
}); });
@ -320,10 +304,8 @@ void SponsoredMessages::append(
.photoId = data.vphoto() .photoId = data.vphoto()
? history->session().data().processPhoto(*data.vphoto())->id ? history->session().data().processPhoto(*data.vphoto())->id
: PhotoId(0), : PhotoId(0),
.mediaPhotoId = (mediaPhoto ? mediaPhoto->owner()->id : PhotoId(0)), .mediaPhotoId = (mediaPhoto ? mediaPhoto->id : 0),
.mediaDocumentId = (mediaDocument .mediaDocumentId = (mediaDocument ? mediaDocument->id : 0),
? mediaDocument->owner()->id
: DocumentId(0)),
.backgroundEmojiId = data.vcolor().has_value() .backgroundEmojiId = data.vcolor().has_value()
? data.vcolor()->data().vbackground_emoji_id().value_or_empty() ? data.vcolor()->data().vbackground_emoji_id().value_or_empty()
: uint64(0), : uint64(0),
@ -358,29 +340,54 @@ void SponsoredMessages::append(
.additionalInfo = std::move(additionalInfo), .additionalInfo = std::move(additionalInfo),
}; };
list.entries.push_back({ list.entries.push_back({
nullptr, .sponsored = std::move(sharedMessage),
{},
std::move(sharedMessage),
mediaPhoto,
mediaDocument,
}); });
auto &entry = list.entries.back();
const auto fileOrigin = FullMsgId( const auto itemId = entry.itemFullId = FullMsgId(
history->peer->id, history->peer->id,
_session->data().nextLocalMessageId()); _session->data().nextLocalMessageId());
list.entries.back().itemFullId = fileOrigin; const auto fileOrigin = FileOrigin(); // No way to refresh in ads.
static const auto kFlaggedPreload = ((MediaPreload*)nullptr) + 1;
const auto preloaded = [=] {
const auto i = _data.find(history);
if (i == end(_data)) {
return;
}
auto &entries = i->second.entries;
const auto j = ranges::find(entries, itemId, &Entry::itemFullId);
if (j == end(entries)) {
return;
}
auto &entry = *j;
if (entry.preload.get() == kFlaggedPreload) {
entry.preload.release();
} else {
entry.preload = nullptr;
}
};
auto preload = std::unique_ptr<MediaPreload>();
entry.preload.reset(kFlaggedPreload);
if (mediaPhoto) { if (mediaPhoto) {
mediaPhoto->owner()->load( preload = std::make_unique<PhotoPreload>(
list.entries.back().itemFullId, mediaPhoto,
LoadFromCloudOrLocal,
true);
}
if (mediaDocument) {
mediaDocument->owner()->save(
fileOrigin, fileOrigin,
QString(), preloaded);
LoadFromCloudOrLocal, } else if (mediaDocument && VideoPreload::Can(mediaDocument)) {
true); preload = std::make_unique<VideoPreload>(
mediaDocument,
fileOrigin,
preloaded);
}
// Preload constructor may have called preloaded(), which zero-ed
// entry.preload, that way we're ready and don't need to save it.
// Otherwise we're preloading and need to save the task.
if (entry.preload.get() == kFlaggedPreload) {
entry.preload.release();
if (preload) {
entry.preload = std::move(preload);
}
} }
} }

View file

@ -20,8 +20,7 @@ class Session;
namespace Data { namespace Data {
class DocumentMedia; class MediaPreload;
class PhotoMedia;
struct SponsoredReportResult final { struct SponsoredReportResult final {
using Id = QByteArray; using Id = QByteArray;
@ -122,8 +121,7 @@ private:
OwnedItem item; OwnedItem item;
FullMsgId itemFullId; FullMsgId itemFullId;
SponsoredMessage sponsored; SponsoredMessage sponsored;
std::shared_ptr<Data::PhotoMedia> photoMedia; std::unique_ptr<MediaPreload> preload;
std::shared_ptr<Data::DocumentMedia> documentMedia;
}; };
struct List { struct List {
std::vector<Entry> entries; std::vector<Entry> entries;