2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-31 06:26:18 +00:00

Update API scheme to layer 183. Paid media.

This commit is contained in:
John Preston
2024-06-18 14:02:05 +04:00
parent e71a067f4b
commit 3ece9b1566
25 changed files with 227 additions and 533 deletions

View File

@@ -7,12 +7,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "data/data_media_types.h"
#include "base/random.h"
#include "history/history.h"
#include "history/history_item.h" // CreateMedia.
#include "history/history_location_manager.h"
#include "history/view/history_view_element.h"
#include "history/view/history_view_item_preview.h"
#include "history/view/media/history_view_extended_preview.h"
#include "history/view/media/history_view_photo.h"
#include "history/view/media/history_view_sticker.h"
#include "history/view/media/history_view_gif.h"
@@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_giveaway.h"
#include "history/view/media/history_view_invoice.h"
#include "history/view/media/history_view_media_generic.h"
#include "history/view/media/history_view_media_grouped.h"
#include "history/view/media/history_view_call.h"
#include "history/view/media/history_view_web_page.h"
#include "history/view/media/history_view_poll.h"
@@ -261,48 +262,80 @@ template <typename MediaType>
}
bool UpdateExtendedMedia(
Invoice &invoice,
std::unique_ptr<Media> &media,
not_null<HistoryItem*> item,
const MTPMessageExtendedMedia &media) {
return media.match([&](const MTPDmessageExtendedMediaPreview &data) {
if (invoice.extendedMedia) {
return false;
const MTPMessageExtendedMedia &extended) {
return extended.match([&](const MTPDmessageExtendedMediaPreview &data) {
auto photo = (PhotoData*)nullptr;
if (!media) {
const auto id = base::RandomValue<PhotoId>();
photo = item->history()->owner().photo(id);
} else {
photo = media->photo();
if (!photo || !photo->extendedMediaPreview()) {
return false;
}
}
auto changed = false;
auto &preview = invoice.extendedPreview;
auto size = QSize();
auto thumbnail = QByteArray();
auto videoDuration = TimeId();
if (const auto &w = data.vw()) {
const auto &h = data.vh();
Assert(h.has_value());
const auto dimensions = QSize(w->v, h->v);
if (preview.dimensions != dimensions) {
preview.dimensions = dimensions;
size = QSize(w->v, h->v);
if (!changed && photo->size(PhotoSize::Large) != size) {
changed = true;
}
}
if (const auto &thumb = data.vthumb()) {
if (thumb->type() == mtpc_photoStrippedSize) {
const auto bytes = thumb->c_photoStrippedSize().vbytes().v;
if (preview.inlineThumbnailBytes != bytes) {
preview.inlineThumbnailBytes = bytes;
thumbnail = thumb->c_photoStrippedSize().vbytes().v;
if (!changed && photo->inlineThumbnailBytes() != thumbnail) {
changed = true;
}
}
}
if (const auto &duration = data.vvideo_duration()) {
if (preview.videoDuration != duration->v) {
preview.videoDuration = duration->v;
videoDuration = duration->v;
if (photo->extendedMediaVideoDuration() != videoDuration) {
changed = true;
}
}
if (changed) {
photo->setExtendedMediaPreview(size, thumbnail, videoDuration);
}
if (!media) {
media = std::make_unique<MediaPhoto>(item, photo, true);
}
return changed;
}, [&](const MTPDmessageExtendedMedia &data) {
invoice.extendedMedia = HistoryItem::CreateMedia(
item,
data.vmedia());
media = HistoryItem::CreateMedia(item, data.vmedia());
return true;
});
}
bool UpdateExtendedMedia(
Invoice &invoice,
not_null<HistoryItem*> item,
const QVector<MTPMessageExtendedMedia> &media) {
auto changed = false;
const auto count = int(media.size());
for (auto i = 0; i != count; ++i) {
if (i < invoice.extendedMedia.size()) {
invoice.extendedMedia.emplace_back();
changed = true;
}
UpdateExtendedMedia(invoice.extendedMedia[i], item, media[i]);
}
if (count < invoice.extendedMedia.size()) {
invoice.extendedMedia.resize(count);
changed = true;
}
return changed;
}
TextForMimeData WithCaptionClipboardText(
const QString &attachType,
TextForMimeData &&caption) {
@@ -344,11 +377,22 @@ Invoice ComputeInvoiceData(
.isTest = data.is_test(),
};
if (const auto &media = data.vextended_media()) {
UpdateExtendedMedia(result, item, *media);
UpdateExtendedMedia(result, item, { *media });
}
return result;
}
Invoice ComputeInvoiceData(
not_null<HistoryItem*> item,
const MTPDmessageMediaPaidMedia &data) {
auto result = Invoice{
.amount = data.vstars_amount().v,
.currency = Ui::kCreditsCurrency,
};
UpdateExtendedMedia(result, item, data.vextended_media().v);
return result;
}
Call ComputeCallData(const MTPDmessageActionPhoneCall &call) {
auto result = Call();
result.finishReason = [&] {
@@ -424,6 +468,18 @@ GiveawayResults ComputeGiveawayResultsData(
return result;
}
bool HasExtendedMedia(const Invoice &invoice) {
return !invoice.extendedMedia.empty();
}
bool HasUnpaidMedia(const Invoice &invoice) {
for (const auto &media : invoice.extendedMedia) {
const auto photo = media->photo();
return photo && photo->extendedMediaPreview();
}
return false;
}
Media::Media(not_null<HistoryItem*> parent) : _parent(parent) {
}
@@ -1851,14 +1907,14 @@ MediaInvoice::MediaInvoice(
.currency = data.currency,
.title = data.title,
.description = data.description,
.extendedPreview = data.extendedPreview,
.extendedMedia = (data.extendedMedia
? data.extendedMedia->clone(parent)
: nullptr),
.photo = data.photo,
.isTest = data.isTest,
} {
if (_invoice.extendedPreview && !_invoice.extendedMedia) {
_invoice.extendedMedia.reserve(data.extendedMedia.size());
for (auto &item : data.extendedMedia) {
_invoice.extendedMedia.push_back(item->clone(parent));
}
if (HasUnpaidMedia(_invoice)) {
Ui::PreloadImageSpoiler();
}
}
@@ -1917,7 +1973,7 @@ bool MediaInvoice::updateSentMedia(const MTPMessageMedia &media) {
bool MediaInvoice::updateExtendedMedia(
not_null<HistoryItem*> item,
const MTPMessageExtendedMedia &media) {
const QVector<MTPMessageExtendedMedia> &media) {
Expects(item == parent());
return UpdateExtendedMedia(_invoice, item, media);
@@ -1927,15 +1983,15 @@ std::unique_ptr<HistoryView::Media> MediaInvoice::createView(
not_null<HistoryView::Element*> message,
not_null<HistoryItem*> realParent,
HistoryView::Element *replacing) {
if (_invoice.extendedMedia) {
return _invoice.extendedMedia->createView(
if (_invoice.extendedMedia.size() == 1) {
return _invoice.extendedMedia.front()->createView(
message,
realParent,
replacing);
} else if (_invoice.extendedPreview) {
return std::make_unique<HistoryView::ExtendedPreview>(
} else if (!_invoice.extendedMedia.empty()) {
return std::make_unique<HistoryView::GroupedMedia>(
message,
&_invoice);
_invoice.extendedMedia);
}
return std::make_unique<HistoryView::Invoice>(message, &_invoice);
}

View File

@@ -84,19 +84,6 @@ struct Call {
};
struct ExtendedPreview {
QByteArray inlineThumbnailBytes;
QSize dimensions;
TimeId videoDuration = -1;
[[nodiscard]] bool empty() const {
return dimensions.isEmpty();
}
explicit operator bool() const {
return !empty();
}
};
class Media;
struct Invoice {
@@ -105,11 +92,12 @@ struct Invoice {
QString currency;
QString title;
TextWithEntities description;
ExtendedPreview extendedPreview;
std::unique_ptr<Media> extendedMedia;
std::vector<std::unique_ptr<Media>> extendedMedia;
PhotoData *photo = nullptr;
bool isTest = false;
};
[[nodiscard]] bool HasExtendedMedia(const Invoice &invoice);
[[nodiscard]] bool HasUnpaidMedia(const Invoice &invoice);
struct GiveawayStart {
std::vector<not_null<ChannelData*>> channels;
@@ -207,7 +195,7 @@ public:
virtual bool updateSentMedia(const MTPMessageMedia &media) = 0;
virtual bool updateExtendedMedia(
not_null<HistoryItem*> item,
const MTPMessageExtendedMedia &media) {
const QVector<MTPMessageExtendedMedia> &media) {
return false;
}
virtual std::unique_ptr<HistoryView::Media> createView(
@@ -524,7 +512,7 @@ public:
bool updateSentMedia(const MTPMessageMedia &media) override;
bool updateExtendedMedia(
not_null<HistoryItem*> item,
const MTPMessageExtendedMedia &media) override;
const QVector<MTPMessageExtendedMedia> &media) override;
std::unique_ptr<HistoryView::Media> createView(
not_null<HistoryView::Element*> message,
not_null<HistoryItem*> realParent,
@@ -750,6 +738,9 @@ private:
[[nodiscard]] Invoice ComputeInvoiceData(
not_null<HistoryItem*> item,
const MTPDmessageMediaInvoice &data);
[[nodiscard]] Invoice ComputeInvoiceData(
not_null<HistoryItem*> item,
const MTPDmessageMediaPaidMedia &data);
[[nodiscard]] Call ComputeCallData(const MTPDmessageActionPhoneCall &call);

View File

@@ -50,6 +50,38 @@ PhotoData::~PhotoData() {
base::take(_videoSizes);
}
void PhotoData::setFields(TimeId date, bool hasAttachedStickers) {
_dateOrExtendedVideoDuration = date;
_hasStickers = hasAttachedStickers;
_extendedMediaPreview = false;
}
void PhotoData::setExtendedMediaPreview(
QSize dimensions,
const QByteArray &inlineThumbnailBytes,
TimeId videoDuration) {
_extendedMediaPreview = true;
updateImages(
inlineThumbnailBytes,
{},
{},
{ .location = { {}, dimensions.width(), dimensions.height() } },
{},
{},
{});
_dateOrExtendedVideoDuration = videoDuration + 1;
}
bool PhotoData::extendedMediaPreview() const {
return _extendedMediaPreview;
}
std::optional<TimeId> PhotoData::extendedMediaVideoDuration() const {
return (_extendedMediaPreview && _dateOrExtendedVideoDuration)
? TimeId(_dateOrExtendedVideoDuration - 1)
: std::optional<TimeId>();
}
Data::Session &PhotoData::owner() const {
return *_owner;
}
@@ -74,6 +106,10 @@ void PhotoData::load(
load(PhotoSize::Large, origin, fromCloud, autoLoading);
}
TimeId PhotoData::date() const {
return _extendedMediaPreview ? 0 : _dateOrExtendedVideoDuration;
}
bool PhotoData::loading() const {
return loading(PhotoSize::Large);
}

View File

@@ -53,6 +53,7 @@ public:
void automaticLoadSettingsChanged();
[[nodiscard]] TimeId date() const;
[[nodiscard]] bool loading() const;
[[nodiscard]] bool displayLoading() const;
void cancel();
@@ -89,6 +90,14 @@ public:
[[nodiscard]] auto activeMediaView() const
-> std::shared_ptr<Data::PhotoMedia>;
void setFields(TimeId date, bool hasAttachedStickers);
void setExtendedMediaPreview(
QSize dimensions,
const QByteArray &inlineThumbnailBytes,
TimeId videoDuration);
[[nodiscard]] bool extendedMediaPreview() const;
[[nodiscard]] std::optional<TimeId> extendedMediaVideoDuration() const;
void updateImages(
const QByteArray &inlineThumbnailBytes,
const ImageWithLocation &small,
@@ -148,11 +157,10 @@ public:
void setHasAttachedStickers(bool value);
// For now they return size of the 'large' image.
int width() const;
int height() const;
[[nodiscard]] int width() const;
[[nodiscard]] int height() const;
PhotoId id = 0;
TimeId date = 0;
PeerData *peer = nullptr; // for chat and channel photos connection
// geo, caption
@@ -164,6 +172,8 @@ private:
[[nodiscard]] const Data::CloudFile &videoFile(
Data::PhotoSize size) const;
TimeId _dateOrExtendedVideoDuration = 0;
struct VideoSizes {
Data::CloudFile small;
Data::CloudFile large;
@@ -177,6 +187,8 @@ private:
int32 _dc = 0;
uint64 _access = 0;
bool _hasStickers = false;
bool _extendedMediaPreview = false;
QByteArray _fileReference;
std::unique_ptr<Data::ReplyPreview> _replyPreview;
std::weak_ptr<Data::PhotoMedia> _media;

View File

@@ -3077,8 +3077,7 @@ void Session::photoApplyFields(
return;
}
photo->setRemoteLocation(dc, access, fileReference);
photo->date = date;
photo->setHasAttachedStickers(hasStickers);
photo->setFields(date, hasStickers);
photo->updateImages(
inlineThumbnailBytes,
small,