diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index 97b54a563..a2c8134ff 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -1334,6 +1334,7 @@ std::unique_ptr MediaFile::createView( message, realParent, _document, + _videoCover, _spoiler); } } else if (_document->isAnimation() || _document->isVideoFile()) { @@ -1341,6 +1342,7 @@ std::unique_ptr MediaFile::createView( message, realParent, _document, + _videoCover, _spoiler); } else if (_document->isTheme() && _document->hasThumbnail()) { return std::make_unique( @@ -2609,6 +2611,7 @@ std::unique_ptr MediaStory::createView( message, realParent, story->document(), + nullptr, spoiler); } } diff --git a/Telegram/SourceFiles/history/view/media/history_view_game.cpp b/Telegram/SourceFiles/history/view/media/history_view_game.cpp index d8a92fdce..5bd71f4e4 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_game.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_game.cpp @@ -69,7 +69,10 @@ QSize Game::countOptimalSize() { // init attach if (!_attach) { - _attach = CreateAttach(_parent, _data->document, _data->photo); + _attach = CreateAttach( + _parent, + _data->document, + _data->document ? nullptr : _data->photo); } // init strings diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp index dbdf7e126..d865b6dbe 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp @@ -48,6 +48,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/ui_utility.h" #include "ui/effects/path_shift_gradient.h" #include "ui/effects/spoiler_mess.h" +#include "data/data_photo.h" +#include "data/data_photo_media.h" #include "data/data_session.h" #include "data/data_stories.h" #include "data/data_streaming.h" @@ -140,9 +142,11 @@ Gif::Gif( not_null parent, not_null realParent, not_null document, + PhotoData *videoCover, bool spoiler) : File(parent, realParent) , _data(document) +, _videoCover(videoCover) , _storyId(realParent->media() ? realParent->media()->storyId() : FullStoryId()) @@ -200,6 +204,12 @@ Gif::Gif( if ((_dataMedia = _data->activeMediaView())) { dataMediaCreated(); + } else if (_videoCover) { + if (_videoCover->inlineThumbnailBytes().isEmpty() + && (_videoCover->hasExact(Data::PhotoSize::Small) + || _videoCover->hasExact(Data::PhotoSize::Thumbnail))) { + _videoCover->load(Data::PhotoSize::Small, realParent->fullId()); + } } else { _data->loadThumbnail(realParent->fullId()); if (!autoplayEnabled()) { @@ -955,6 +965,8 @@ QImage Gif::spoilerTagBackground() const { } void Gif::validateVideoThumbnail() const { + Expects(!_videoCover); + const auto content = _dataMedia->videoThumbnailContent(); if (_videoThumbnailFrame || content.isEmpty()) { return; @@ -970,13 +982,25 @@ void Gif::validateThumbCache( QSize outer, bool isEllipse, std::optional rounding) const { - const auto good = _dataMedia->goodThumbnail(); - const auto normal = good ? good : _dataMedia->thumbnail(); + const auto good = _videoCoverMedia + ? _videoCoverMedia->image(Data::PhotoSize::Large) + : _dataMedia->goodThumbnail(); + const auto normal = good + ? good + : _videoCoverMedia + ? nullptr + : _dataMedia->thumbnail(); if (!normal) { - _data->loadThumbnail(_realParent->fullId()); - validateVideoThumbnail(); + if (_videoCoverMedia) { + _videoCover->load(Data::PhotoSize::Small, _realParent->fullId()); + } else { + _data->loadThumbnail(_realParent->fullId()); + validateVideoThumbnail(); + } } - const auto videothumb = normal ? nullptr : _videoThumbnailFrame.get(); + const auto videothumb = (normal || _videoCoverMedia) + ? nullptr + : _videoThumbnailFrame.get(); const auto blurred = normal ? (!good && (normal->width() < kUseNonBlurredThreshold) @@ -998,9 +1022,17 @@ void Gif::validateThumbCache( } QImage Gif::prepareThumbCache(QSize outer) const { - const auto good = _dataMedia->goodThumbnail(); - const auto normal = good ? good : _dataMedia->thumbnail(); - const auto videothumb = normal ? nullptr : _videoThumbnailFrame.get(); + const auto good = _videoCoverMedia + ? _videoCoverMedia->image(Data::PhotoSize::Large) + : _dataMedia->goodThumbnail(); + const auto normal = good + ? good + : _videoCoverMedia + ? nullptr + : _dataMedia->thumbnail(); + const auto videothumb = (normal || _videoCoverMedia) + ? nullptr + : _videoThumbnailFrame.get(); auto blurred = (!good && normal && (normal->width() < kUseNonBlurredThreshold) @@ -1010,6 +1042,10 @@ QImage Gif::prepareThumbCache(QSize outer) const { const auto blurFromLarge = good || (normal && !blurred); const auto large = blurFromLarge ? normal : videothumb; if (videothumb) { + } else if (_videoCoverMedia) { + if (const auto embedded = _videoCoverMedia->thumbnailInline()) { + blurred = embedded; + } } else if (const auto embedded = _dataMedia->thumbnailInline()) { blurred = embedded; } @@ -1035,7 +1071,9 @@ void Gif::validateSpoilerImageCache( && _spoiler->backgroundRounding == rounding) { return; } - const auto normal = _dataMedia->thumbnail(); + const auto normal = _videoCoverMedia + ? _videoCoverMedia->image(Data::PhotoSize::Small) + : _dataMedia->thumbnail(); auto container = std::optional(); const auto downscale = [&](Image *image) { if (!image || (image->width() <= 40 && image->height() <= 40)) { @@ -1047,7 +1085,9 @@ void Gif::validateSpoilerImageCache( Qt::SmoothTransformation)); return &*container; }; - const auto embedded = _dataMedia->thumbnailInline(); + const auto embedded = _videoCoverMedia + ? _videoCoverMedia->thumbnailInline() + : _dataMedia->thumbnailInline(); const auto blurred = embedded ? embedded : downscale(normal); _spoiler->background = Images::Round( PrepareWithBlurredBackground( @@ -1584,20 +1624,29 @@ TextState Gif::getStateGrouped( } void Gif::ensureDataMediaCreated() const { - if (_dataMedia) { + if (_dataMedia && (!_videoCover || _videoCoverMedia)) { return; } _dataMedia = _data->createMediaView(); + _videoCoverMedia = _videoCover + ? _videoCover->createMediaView() + : nullptr; dataMediaCreated(); } void Gif::dataMediaCreated() const { Expects(_dataMedia != nullptr); - _dataMedia->goodThumbnailWanted(); - _dataMedia->thumbnailWanted(_realParent->fullId()); - if (!autoplayEnabled()) { - _dataMedia->videoThumbnailWanted(_realParent->fullId()); + if (_videoCoverMedia) { + _videoCoverMedia->wanted( + Data::PhotoSize::Large, + _realParent->fullId()); + } else { + _dataMedia->goodThumbnailWanted(); + _dataMedia->thumbnailWanted(_realParent->fullId()); + if (!autoplayEnabled()) { + _dataMedia->videoThumbnailWanted(_realParent->fullId()); + } } history()->owner().registerHeavyViewPart(_parent); togglePollingStory(true); diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.h b/Telegram/SourceFiles/history/view/media/history_view_gif.h index 635e3627d..35a510c06 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.h +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.h @@ -15,9 +15,11 @@ struct HistoryMessageVia; struct HistoryMessageReply; struct HistoryMessageForwarded; class Painter; +class PhotoData; namespace Data { class DocumentMedia; +class PhotoMedia; } // namespace Data namespace Media { @@ -37,6 +39,7 @@ enum class Error; namespace HistoryView { +class Photo; class Reply; class TranscribeButton; @@ -51,6 +54,7 @@ public: not_null parent, not_null realParent, not_null document, + PhotoData *videoCover, bool spoiler); ~Gif(); @@ -212,12 +216,14 @@ private: TtlRoundPaintCallback _drawTtl; const not_null _data; + PhotoData *_videoCover = nullptr; const FullStoryId _storyId; std::unique_ptr _streamed; const std::unique_ptr _spoiler; mutable std::unique_ptr _spoilerTag; mutable std::unique_ptr _transcribe; mutable std::shared_ptr _dataMedia; + mutable std::shared_ptr _videoCoverMedia; mutable std::unique_ptr _videoThumbnailFrame; QString _downloadSize; mutable QImage _thumbCache; diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_common.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_common.cpp index b899d9fc9..9364648a3 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_common.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_common.cpp @@ -101,6 +101,7 @@ std::unique_ptr CreateAttach( parent, parent->data(), document, + photo, spoiler); } else if (document->isWallPaper() || document->isTheme()) { return std::make_unique( diff --git a/Telegram/SourceFiles/history/view/media/history_view_photo.h b/Telegram/SourceFiles/history/view/media/history_view_photo.h index 710901f76..14c6f8344 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_photo.h +++ b/Telegram/SourceFiles/history/view/media/history_view_photo.h @@ -114,7 +114,6 @@ private: void ensureDataMediaCreated() const; void dataMediaCreated() const; - void setupSpoilerTag() const; QSize countOptimalSize() override; QSize countCurrentSize(int newWidth) override; diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp index 84019e776..b0ab08952 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp @@ -309,13 +309,13 @@ void WebPage::setupAdditionalData() { UrlClickHandler::Open(link); }); if (!_attach) { - const auto maybePhoto = details.mediaPhotoId - ? session->data().photo(details.mediaPhotoId).get() - : nullptr; const auto maybeDocument = details.mediaDocumentId ? session->data().document( details.mediaDocumentId).get() : nullptr; + const auto maybePhoto = (!maybeDocument && details.mediaPhotoId) + ? session->data().photo(details.mediaPhotoId).get() + : nullptr; _attach = CreateAttach( _parent, maybeDocument, @@ -520,7 +520,9 @@ QSize WebPage::countOptimalSize() { _attach = CreateAttach( _parent, _data->document, - _data->photo, + ((!_data->document || _data->photoIsVideoCover) + ? _data->photo + : nullptr), _collage, _data->url); }