mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Show correct chat preview for paid media.
This commit is contained in:
parent
5f8da27c86
commit
950a946a16
9 changed files with 184 additions and 54 deletions
|
@ -4214,11 +4214,18 @@ void ApiWrap::sendMediaWithRandomId(
|
||||||
|
|
||||||
void ApiWrap::sendMultiPaidMedia(
|
void ApiWrap::sendMultiPaidMedia(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
const QVector<MTPInputMedia> &medias,
|
not_null<SendingAlbum*> album,
|
||||||
Api::SendOptions options,
|
|
||||||
uint64 randomId,
|
|
||||||
Fn<void(bool)> done) {
|
Fn<void(bool)> done) {
|
||||||
Expects(options.price > 0);
|
Expects(album->options.price > 0);
|
||||||
|
|
||||||
|
const auto groupId = album->groupId;
|
||||||
|
const auto &options = album->options;
|
||||||
|
const auto randomId = album->items.front().randomId;
|
||||||
|
auto medias = album->items | ranges::view::transform([](
|
||||||
|
const SendingAlbum::Item &part) {
|
||||||
|
Assert(part.media.has_value());
|
||||||
|
return MTPInputMedia(part.media->data().vmedia());
|
||||||
|
}) | ranges::to<QVector<MTPInputMedia>>();
|
||||||
|
|
||||||
const auto history = item->history();
|
const auto history = item->history();
|
||||||
const auto replyTo = item->replyTo();
|
const auto replyTo = item->replyTo();
|
||||||
|
@ -4256,7 +4263,7 @@ void ApiWrap::sendMultiPaidMedia(
|
||||||
Data::Histories::ReplyToPlaceholder(),
|
Data::Histories::ReplyToPlaceholder(),
|
||||||
MTP_inputMediaPaidMedia(
|
MTP_inputMediaPaidMedia(
|
||||||
MTP_long(options.price),
|
MTP_long(options.price),
|
||||||
MTP_vector<MTPInputMedia>(medias)),
|
MTP_vector<MTPInputMedia>(std::move(medias))),
|
||||||
MTP_string(caption.text),
|
MTP_string(caption.text),
|
||||||
MTP_long(randomId),
|
MTP_long(randomId),
|
||||||
MTPReplyMarkup(),
|
MTPReplyMarkup(),
|
||||||
|
@ -4266,6 +4273,14 @@ void ApiWrap::sendMultiPaidMedia(
|
||||||
Data::ShortcutIdToMTP(_session, options.shortcutId),
|
Data::ShortcutIdToMTP(_session, options.shortcutId),
|
||||||
MTP_long(options.effectId)
|
MTP_long(options.effectId)
|
||||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||||
|
if (const auto album = _sendingAlbums.take(groupId)) {
|
||||||
|
const auto copy = (*album)->items;
|
||||||
|
for (const auto &part : copy) {
|
||||||
|
if (const auto item = history->owner().message(part.msgId)) {
|
||||||
|
item->destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (done) done(true);
|
if (done) done(true);
|
||||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||||
if (done) done(false);
|
if (done) done(false);
|
||||||
|
@ -4326,6 +4341,9 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
||||||
if (!sample) {
|
if (!sample) {
|
||||||
_sendingAlbums.remove(groupId);
|
_sendingAlbums.remove(groupId);
|
||||||
return;
|
return;
|
||||||
|
} else if (album->options.price > 0) {
|
||||||
|
sendMultiPaidMedia(sample, album);
|
||||||
|
return;
|
||||||
} else if (medias.size() < 2) {
|
} else if (medias.size() < 2) {
|
||||||
const auto &single = medias.front().data();
|
const auto &single = medias.front().data();
|
||||||
sendMediaWithRandomId(
|
sendMediaWithRandomId(
|
||||||
|
@ -4335,19 +4353,6 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
||||||
single.vrandom_id().v);
|
single.vrandom_id().v);
|
||||||
_sendingAlbums.remove(groupId);
|
_sendingAlbums.remove(groupId);
|
||||||
return;
|
return;
|
||||||
} else if (album->options.price > 0) {
|
|
||||||
const auto &single = medias.front().data();
|
|
||||||
auto list = medias | ranges::view::transform([](
|
|
||||||
const MTPInputSingleMedia &media) {
|
|
||||||
return MTPInputMedia(media.data().vmedia());
|
|
||||||
}) | ranges::to<QVector<MTPInputMedia>>();
|
|
||||||
sendMultiPaidMedia(
|
|
||||||
sample,
|
|
||||||
std::move(list),
|
|
||||||
album->options,
|
|
||||||
single.vrandom_id().v);
|
|
||||||
_sendingAlbums.remove(groupId);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const auto history = sample->history();
|
const auto history = sample->history();
|
||||||
const auto replyTo = sample->replyTo();
|
const auto replyTo = sample->replyTo();
|
||||||
|
|
|
@ -547,9 +547,7 @@ private:
|
||||||
Fn<void(bool)> done = nullptr);
|
Fn<void(bool)> done = nullptr);
|
||||||
void sendMultiPaidMedia(
|
void sendMultiPaidMedia(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
const QVector<MTPInputMedia> &medias,
|
not_null<SendingAlbum*> album,
|
||||||
Api::SendOptions options,
|
|
||||||
uint64 randomId,
|
|
||||||
Fn<void(bool)> done = nullptr);
|
Fn<void(bool)> done = nullptr);
|
||||||
|
|
||||||
void getTopPromotionDelayed(TimeId now, TimeId next);
|
void getTopPromotionDelayed(TimeId now, TimeId next);
|
||||||
|
|
|
@ -81,6 +81,7 @@ void Groups::refreshMessage(
|
||||||
bool justRefreshViews) {
|
bool justRefreshViews) {
|
||||||
if (!isGrouped(item)) {
|
if (!isGrouped(item)) {
|
||||||
unregisterMessage(item);
|
unregisterMessage(item);
|
||||||
|
_data->requestItemViewRefresh(item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!item->isRegular() && !item->isScheduled()) {
|
if (!item->isRegular() && !item->isScheduled()) {
|
||||||
|
|
|
@ -85,6 +85,13 @@ constexpr auto kLoadingStoryPhotoId = PhotoId(0x7FFF'DEAD'FFFF'FFFFULL);
|
||||||
using ItemPreview = HistoryView::ItemPreview;
|
using ItemPreview = HistoryView::ItemPreview;
|
||||||
using ItemPreviewImage = HistoryView::ItemPreviewImage;
|
using ItemPreviewImage = HistoryView::ItemPreviewImage;
|
||||||
|
|
||||||
|
struct AlbumCounts {
|
||||||
|
int photos = 0;
|
||||||
|
int videos = 0;
|
||||||
|
int audios = 0;
|
||||||
|
int files = 0;
|
||||||
|
};
|
||||||
|
|
||||||
[[nodiscard]] TextWithEntities WithCaptionNotificationText(
|
[[nodiscard]] TextWithEntities WithCaptionNotificationText(
|
||||||
const QString &attachType,
|
const QString &attachType,
|
||||||
const TextWithEntities &caption,
|
const TextWithEntities &caption,
|
||||||
|
@ -166,7 +173,7 @@ template <typename MediaType>
|
||||||
return (reinterpret_cast<uint64>(data.get()) & ~1) | (spoiler ? 1 : 0);
|
return (reinterpret_cast<uint64>(data.get()) & ~1) | (spoiler ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] ItemPreviewImage PreparePhotoPreview(
|
[[nodiscard]] ItemPreviewImage PreparePhotoPreviewImage(
|
||||||
not_null<const HistoryItem*> item,
|
not_null<const HistoryItem*> item,
|
||||||
const std::shared_ptr<PhotoMedia> &media,
|
const std::shared_ptr<PhotoMedia> &media,
|
||||||
ImageRoundRadius radius,
|
ImageRoundRadius radius,
|
||||||
|
@ -182,14 +189,15 @@ template <typename MediaType>
|
||||||
}
|
}
|
||||||
const auto allowedToDownload = media->autoLoadThumbnailAllowed(
|
const auto allowedToDownload = media->autoLoadThumbnailAllowed(
|
||||||
item->history()->peer);
|
item->history()->peer);
|
||||||
const auto cacheKey = allowedToDownload ? 0 : counted;
|
const auto spoilered = uint64(spoiler ? 1 : 0);
|
||||||
|
const auto cacheKey = allowedToDownload ? spoilered : counted;
|
||||||
if (allowedToDownload) {
|
if (allowedToDownload) {
|
||||||
media->owner()->load(PhotoSize::Small, item->fullId());
|
media->owner()->load(PhotoSize::Small, item->fullId());
|
||||||
}
|
}
|
||||||
if (const auto blurred = media->thumbnailInline()) {
|
if (const auto blurred = media->thumbnailInline()) {
|
||||||
return { PreparePreviewImage(blurred, radius, spoiler), cacheKey };
|
return { PreparePreviewImage(blurred, radius, spoiler), cacheKey };
|
||||||
}
|
}
|
||||||
return { QImage(), allowedToDownload ? 0 : cacheKey };
|
return { QImage(), allowedToDownload ? spoilered : cacheKey };
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] ItemPreviewImage PrepareFilePreviewImage(
|
[[nodiscard]] ItemPreviewImage PrepareFilePreviewImage(
|
||||||
|
@ -208,10 +216,11 @@ template <typename MediaType>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
document->loadThumbnail(item->fullId());
|
document->loadThumbnail(item->fullId());
|
||||||
|
const auto spoilered = uint64(spoiler ? 1 : 0);
|
||||||
if (const auto blurred = media->thumbnailInline()) {
|
if (const auto blurred = media->thumbnailInline()) {
|
||||||
return { PreparePreviewImage(blurred, radius, spoiler), 0 };
|
return { PreparePreviewImage(blurred, radius, spoiler), spoilered };
|
||||||
}
|
}
|
||||||
return { QImage(), 0 };
|
return { QImage(), spoilered };
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] QImage PutPlayIcon(QImage preview) {
|
[[nodiscard]] QImage PutPlayIcon(QImage preview) {
|
||||||
|
@ -226,6 +235,18 @@ template <typename MediaType>
|
||||||
return preview;
|
return preview;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ItemPreviewImage PreparePhotoPreview(
|
||||||
|
not_null<const HistoryItem*> item,
|
||||||
|
const std::shared_ptr<PhotoMedia> &media,
|
||||||
|
ImageRoundRadius radius,
|
||||||
|
bool spoiler) {
|
||||||
|
auto result = PreparePhotoPreviewImage(item, media, radius, spoiler);
|
||||||
|
if (media->owner()->extendedMediaVideoDuration().has_value()) {
|
||||||
|
result.data = PutPlayIcon(std::move(result.data));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] ItemPreviewImage PrepareFilePreview(
|
[[nodiscard]] ItemPreviewImage PrepareFilePreview(
|
||||||
not_null<const HistoryItem*> item,
|
not_null<const HistoryItem*> item,
|
||||||
const std::shared_ptr<DocumentMedia> &media,
|
const std::shared_ptr<DocumentMedia> &media,
|
||||||
|
@ -280,7 +301,7 @@ bool UpdateExtendedMedia(
|
||||||
auto changed = false;
|
auto changed = false;
|
||||||
auto size = QSize();
|
auto size = QSize();
|
||||||
auto thumbnail = QByteArray();
|
auto thumbnail = QByteArray();
|
||||||
auto videoDuration = TimeId();
|
auto videoDuration = std::optional<TimeId>();
|
||||||
if (const auto &w = data.vw()) {
|
if (const auto &w = data.vw()) {
|
||||||
const auto &h = data.vh();
|
const auto &h = data.vh();
|
||||||
Assert(h.has_value());
|
Assert(h.has_value());
|
||||||
|
@ -302,6 +323,8 @@ bool UpdateExtendedMedia(
|
||||||
if (photo->extendedMediaVideoDuration() != videoDuration) {
|
if (photo->extendedMediaVideoDuration() != videoDuration) {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
} else if (photo->extendedMediaVideoDuration().has_value()) {
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
photo->setExtendedMediaPreview(size, thumbnail, videoDuration);
|
photo->setExtendedMediaPreview(size, thumbnail, videoDuration);
|
||||||
|
@ -355,6 +378,29 @@ TextForMimeData WithCaptionClipboardText(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QString ComputeAlbumCountsString(AlbumCounts counts) {
|
||||||
|
const auto medias = counts.photos + counts.videos;
|
||||||
|
return (counts.photos && counts.videos)
|
||||||
|
? tr::lng_in_dlg_media_count(tr::now, lt_count, medias)
|
||||||
|
: (counts.photos > 1)
|
||||||
|
? tr::lng_in_dlg_photo_count(tr::now, lt_count, counts.photos)
|
||||||
|
: counts.photos
|
||||||
|
? tr::lng_in_dlg_photo(tr::now)
|
||||||
|
: (counts.videos > 1)
|
||||||
|
? tr::lng_in_dlg_video_count(tr::now, lt_count, counts.videos)
|
||||||
|
: counts.videos
|
||||||
|
? tr::lng_in_dlg_video(tr::now)
|
||||||
|
: (counts.audios > 1)
|
||||||
|
? tr::lng_in_dlg_audio_count(tr::now, lt_count, counts.audios)
|
||||||
|
: counts.audios
|
||||||
|
? tr::lng_in_dlg_audio(tr::now)
|
||||||
|
: (counts.files > 1)
|
||||||
|
? tr::lng_in_dlg_file_count(tr::now, lt_count, counts.files)
|
||||||
|
: counts.files
|
||||||
|
? tr::lng_in_dlg_file(tr::now)
|
||||||
|
: tr::lng_in_dlg_album(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Invoice ComputeInvoiceData(
|
Invoice ComputeInvoiceData(
|
||||||
|
@ -481,6 +527,15 @@ bool HasUnpaidMedia(const Invoice &invoice) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsFirstVideo(const Invoice &invoice) {
|
||||||
|
if (invoice.extendedMedia.empty()) {
|
||||||
|
return false;
|
||||||
|
} else if (const auto photo = invoice.extendedMedia.front()->photo()) {
|
||||||
|
return photo->extendedMediaVideoDuration().has_value();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Media::Media(not_null<HistoryItem*> parent) : _parent(parent) {
|
Media::Media(not_null<HistoryItem*> parent) : _parent(parent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,21 +698,18 @@ ItemPreview Media::toGroupPreview(
|
||||||
ToPreviewOptions options) const {
|
ToPreviewOptions options) const {
|
||||||
auto result = ItemPreview();
|
auto result = ItemPreview();
|
||||||
auto loadingContext = std::vector<std::any>();
|
auto loadingContext = std::vector<std::any>();
|
||||||
auto photoCount = 0;
|
auto counts = AlbumCounts();
|
||||||
auto videoCount = 0;
|
|
||||||
auto audioCount = 0;
|
|
||||||
auto fileCount = 0;
|
|
||||||
auto manyCaptions = false;
|
auto manyCaptions = false;
|
||||||
for (const auto &item : items) {
|
for (const auto &item : items) {
|
||||||
if (const auto media = item->media()) {
|
if (const auto media = item->media()) {
|
||||||
if (media->photo()) {
|
if (media->photo()) {
|
||||||
photoCount++;
|
counts.photos++;
|
||||||
} else if (const auto document = media->document()) {
|
} else if (const auto document = media->document()) {
|
||||||
(document->isVideoFile()
|
(document->isVideoFile()
|
||||||
? videoCount
|
? counts.videos
|
||||||
: document->isAudioFile()
|
: document->isAudioFile()
|
||||||
? audioCount
|
? counts.audios
|
||||||
: fileCount)++;
|
: counts.files)++;
|
||||||
}
|
}
|
||||||
auto copy = options;
|
auto copy = options;
|
||||||
copy.ignoreGroup = true;
|
copy.ignoreGroup = true;
|
||||||
|
@ -687,19 +739,7 @@ ItemPreview Media::toGroupPreview(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (manyCaptions || result.text.text.isEmpty()) {
|
if (manyCaptions || result.text.text.isEmpty()) {
|
||||||
const auto mediaCount = photoCount + videoCount;
|
result.text = Ui::Text::Colorized(ComputeAlbumCountsString(counts));
|
||||||
auto genericText = (photoCount && videoCount)
|
|
||||||
? tr::lng_in_dlg_media_count(tr::now, lt_count, mediaCount)
|
|
||||||
: photoCount
|
|
||||||
? tr::lng_in_dlg_photo_count(tr::now, lt_count, photoCount)
|
|
||||||
: videoCount
|
|
||||||
? tr::lng_in_dlg_video_count(tr::now, lt_count, videoCount)
|
|
||||||
: audioCount
|
|
||||||
? tr::lng_in_dlg_audio_count(tr::now, lt_count, audioCount)
|
|
||||||
: fileCount
|
|
||||||
? tr::lng_in_dlg_file_count(tr::now, lt_count, fileCount)
|
|
||||||
: tr::lng_in_dlg_album(tr::now);
|
|
||||||
result.text = Ui::Text::Colorized(genericText);
|
|
||||||
}
|
}
|
||||||
if (!loadingContext.empty()) {
|
if (!loadingContext.empty()) {
|
||||||
result.loadingContext = std::move(loadingContext);
|
result.loadingContext = std::move(loadingContext);
|
||||||
|
@ -1952,9 +1992,87 @@ bool MediaInvoice::replyPreviewLoaded() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextWithEntities MediaInvoice::notificationText() const {
|
TextWithEntities MediaInvoice::notificationText() const {
|
||||||
|
if (_invoice.isPaidMedia && !_invoice.extendedMedia.empty()) {
|
||||||
|
return WithCaptionNotificationText(
|
||||||
|
(IsFirstVideo(_invoice)
|
||||||
|
? tr::lng_in_dlg_video
|
||||||
|
: tr::lng_in_dlg_photo)(tr::now),
|
||||||
|
parent()->originalText());
|
||||||
|
}
|
||||||
return { .text = _invoice.title };
|
return { .text = _invoice.title };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemPreview MediaInvoice::toPreview(ToPreviewOptions options) const {
|
||||||
|
if (!_invoice.isPaidMedia || _invoice.extendedMedia.empty()) {
|
||||||
|
return Media::toPreview(options);
|
||||||
|
}
|
||||||
|
auto counts = AlbumCounts();
|
||||||
|
const auto item = parent();
|
||||||
|
auto images = std::vector<ItemPreviewImage>();
|
||||||
|
auto context = std::vector<std::any>();
|
||||||
|
const auto existing = options.existing;
|
||||||
|
const auto spoiler = HasUnpaidMedia(_invoice);
|
||||||
|
for (const auto &media : _invoice.extendedMedia) {
|
||||||
|
const auto raw = media.get();
|
||||||
|
const auto photo = raw->photo();
|
||||||
|
const auto document = raw->document();
|
||||||
|
if (!photo && !document) {
|
||||||
|
continue;
|
||||||
|
} else if (images.size() < kMaxPreviewImages) {
|
||||||
|
auto found = photo
|
||||||
|
? FindCachedPreview(existing, not_null(photo), spoiler)
|
||||||
|
: FindCachedPreview(existing, not_null(document), spoiler);
|
||||||
|
const auto radius = ImageRoundRadius::Small;
|
||||||
|
if (found) {
|
||||||
|
images.push_back(std::move(found));
|
||||||
|
} else if (photo) {
|
||||||
|
const auto media = photo->createMediaView();
|
||||||
|
if (auto prepared = PreparePhotoPreview(
|
||||||
|
parent(),
|
||||||
|
media,
|
||||||
|
radius,
|
||||||
|
spoiler)
|
||||||
|
; prepared || !prepared.cacheKey) {
|
||||||
|
images.push_back(std::move(prepared));
|
||||||
|
if (!prepared.cacheKey) {
|
||||||
|
context.push_back(media);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (TryFilePreview(document)) {
|
||||||
|
const auto media = document->createMediaView();
|
||||||
|
if (auto prepared = PrepareFilePreview(
|
||||||
|
parent(),
|
||||||
|
media,
|
||||||
|
radius,
|
||||||
|
spoiler)
|
||||||
|
; prepared || !prepared.cacheKey) {
|
||||||
|
images.push_back(std::move(prepared));
|
||||||
|
if (!prepared.cacheKey) {
|
||||||
|
context.push_back(media);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (photo && !photo->extendedMediaVideoDuration().has_value()) {
|
||||||
|
++counts.photos;
|
||||||
|
} else {
|
||||||
|
++counts.videos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const auto type = ComputeAlbumCountsString(counts);
|
||||||
|
const auto caption = (options.hideCaption || options.ignoreMessageText)
|
||||||
|
? TextWithEntities()
|
||||||
|
: options.translated
|
||||||
|
? parent()->translatedText()
|
||||||
|
: parent()->originalText();
|
||||||
|
const auto hasMiniImages = !images.empty();
|
||||||
|
return {
|
||||||
|
.text = WithCaptionNotificationText(type, caption, hasMiniImages),
|
||||||
|
.images = std::move(images),
|
||||||
|
.loadingContext = std::move(context),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
QString MediaInvoice::pinnedTextSubstring() const {
|
QString MediaInvoice::pinnedTextSubstring() const {
|
||||||
return QString::fromUtf8("\xC2\xAB")
|
return QString::fromUtf8("\xC2\xAB")
|
||||||
+ _invoice.title
|
+ _invoice.title
|
||||||
|
|
|
@ -99,6 +99,7 @@ struct Invoice {
|
||||||
};
|
};
|
||||||
[[nodiscard]] bool HasExtendedMedia(const Invoice &invoice);
|
[[nodiscard]] bool HasExtendedMedia(const Invoice &invoice);
|
||||||
[[nodiscard]] bool HasUnpaidMedia(const Invoice &invoice);
|
[[nodiscard]] bool HasUnpaidMedia(const Invoice &invoice);
|
||||||
|
[[nodiscard]] bool IsFirstVideo(const Invoice &invoice);
|
||||||
|
|
||||||
struct GiveawayStart {
|
struct GiveawayStart {
|
||||||
std::vector<not_null<ChannelData*>> channels;
|
std::vector<not_null<ChannelData*>> channels;
|
||||||
|
@ -506,6 +507,7 @@ public:
|
||||||
Image *replyPreview() const override;
|
Image *replyPreview() const override;
|
||||||
bool replyPreviewLoaded() const override;
|
bool replyPreviewLoaded() const override;
|
||||||
TextWithEntities notificationText() const override;
|
TextWithEntities notificationText() const override;
|
||||||
|
ItemPreview toPreview(ToPreviewOptions way) const override;
|
||||||
QString pinnedTextSubstring() const override;
|
QString pinnedTextSubstring() const override;
|
||||||
TextForMimeData clipboardText() const override;
|
TextForMimeData clipboardText() const override;
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ void PhotoData::setFields(TimeId date, bool hasAttachedStickers) {
|
||||||
void PhotoData::setExtendedMediaPreview(
|
void PhotoData::setExtendedMediaPreview(
|
||||||
QSize dimensions,
|
QSize dimensions,
|
||||||
const QByteArray &inlineThumbnailBytes,
|
const QByteArray &inlineThumbnailBytes,
|
||||||
TimeId videoDuration) {
|
std::optional<TimeId> videoDuration) {
|
||||||
_extendedMediaPreview = true;
|
_extendedMediaPreview = true;
|
||||||
updateImages(
|
updateImages(
|
||||||
inlineThumbnailBytes,
|
inlineThumbnailBytes,
|
||||||
|
@ -69,7 +69,7 @@ void PhotoData::setExtendedMediaPreview(
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
{});
|
{});
|
||||||
_dateOrExtendedVideoDuration = videoDuration + 1;
|
_dateOrExtendedVideoDuration = videoDuration ? (*videoDuration + 1) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhotoData::extendedMediaPreview() const {
|
bool PhotoData::extendedMediaPreview() const {
|
||||||
|
|
|
@ -94,7 +94,7 @@ public:
|
||||||
void setExtendedMediaPreview(
|
void setExtendedMediaPreview(
|
||||||
QSize dimensions,
|
QSize dimensions,
|
||||||
const QByteArray &inlineThumbnailBytes,
|
const QByteArray &inlineThumbnailBytes,
|
||||||
TimeId videoDuration);
|
std::optional<TimeId> videoDuration);
|
||||||
[[nodiscard]] bool extendedMediaPreview() const;
|
[[nodiscard]] bool extendedMediaPreview() const;
|
||||||
[[nodiscard]] std::optional<TimeId> extendedMediaVideoDuration() const;
|
[[nodiscard]] std::optional<TimeId> extendedMediaVideoDuration() const;
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,11 @@ HistoryItem *GroupedMedia::itemForText() const {
|
||||||
auto result = (HistoryItem*)nullptr;
|
auto result = (HistoryItem*)nullptr;
|
||||||
for (const auto &part : _parts) {
|
for (const auto &part : _parts) {
|
||||||
if (!part.item->emptyText()) {
|
if (!part.item->emptyText()) {
|
||||||
if (result) {
|
if (result == part.item) {
|
||||||
|
// All parts are from the same message, that means
|
||||||
|
// this is an album with a single item, single text.
|
||||||
|
return result;
|
||||||
|
} else if (result) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
result = part.item;
|
result = part.item;
|
||||||
|
|
|
@ -618,7 +618,8 @@ FillMenuResult FillSendMenu(
|
||||||
const auto sending = (type != Type::Disabled);
|
const auto sending = (type != Type::Disabled);
|
||||||
const auto empty = !sending
|
const auto empty = !sending
|
||||||
&& (details.spoiler == SpoilerState::None)
|
&& (details.spoiler == SpoilerState::None)
|
||||||
&& (details.caption == CaptionState::None);
|
&& (details.caption == CaptionState::None)
|
||||||
|
&& !details.price.has_value();
|
||||||
if (empty || !action) {
|
if (empty || !action) {
|
||||||
return FillMenuResult::Skipped;
|
return FillMenuResult::Skipped;
|
||||||
}
|
}
|
||||||
|
@ -651,7 +652,8 @@ FillMenuResult FillSendMenu(
|
||||||
|
|
||||||
if ((type != Type::Disabled)
|
if ((type != Type::Disabled)
|
||||||
&& ((details.spoiler != SpoilerState::None)
|
&& ((details.spoiler != SpoilerState::None)
|
||||||
|| (details.caption != CaptionState::None))) {
|
|| (details.caption != CaptionState::None)
|
||||||
|
|| details.price.has_value())) {
|
||||||
menu->addSeparator(&st::expandedMenuSeparator);
|
menu->addSeparator(&st::expandedMenuSeparator);
|
||||||
}
|
}
|
||||||
if (details.spoiler != SpoilerState::None) {
|
if (details.spoiler != SpoilerState::None) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue