mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 07:07:08 +02:00
Allow to load video components of photos.
This commit is contained in:
parent
1a9c241b96
commit
0126578dbd
9 changed files with 151 additions and 13 deletions
|
@ -166,8 +166,8 @@ public:
|
|||
[[nodiscard]] bool videoThumbnailLoading() const;
|
||||
[[nodiscard]] bool videoThumbnailFailed() const;
|
||||
void loadVideoThumbnail(Data::FileOrigin origin);
|
||||
const ImageLocation &videoThumbnailLocation() const;
|
||||
int videoThumbnailByteSize() const;
|
||||
[[nodiscard]] const ImageLocation &videoThumbnailLocation() const;
|
||||
[[nodiscard]] int videoThumbnailByteSize() const;
|
||||
|
||||
void updateThumbnails(
|
||||
const QByteArray &inlineThumbnailBytes,
|
||||
|
|
|
@ -39,6 +39,7 @@ PhotoData::~PhotoData() {
|
|||
for (auto &image : _images) {
|
||||
base::take(image.loader).reset();
|
||||
}
|
||||
base::take(_video.loader).reset();
|
||||
}
|
||||
|
||||
Data::Session &PhotoData::owner() const {
|
||||
|
@ -294,7 +295,8 @@ void PhotoData::updateImages(
|
|||
const QByteArray &inlineThumbnailBytes,
|
||||
const ImageWithLocation &small,
|
||||
const ImageWithLocation &thumbnail,
|
||||
const ImageWithLocation &large) {
|
||||
const ImageWithLocation &large,
|
||||
const ImageWithLocation &video) {
|
||||
if (!inlineThumbnailBytes.isEmpty()
|
||||
&& _inlineThumbnailBytes.isEmpty()) {
|
||||
_inlineThumbnailBytes = inlineThumbnailBytes;
|
||||
|
@ -315,6 +317,13 @@ void PhotoData::updateImages(
|
|||
update(PhotoSize::Small, small);
|
||||
update(PhotoSize::Thumbnail, thumbnail);
|
||||
update(PhotoSize::Large, large);
|
||||
|
||||
Data::UpdateCloudFile(
|
||||
_video,
|
||||
video,
|
||||
owner().cache(),
|
||||
Data::kAnimationCacheTag,
|
||||
[&](Data::FileOrigin origin) { loadVideo(origin); });
|
||||
}
|
||||
|
||||
int PhotoData::width() const {
|
||||
|
@ -325,6 +334,50 @@ int PhotoData::height() const {
|
|||
return _images[PhotoSizeIndex(PhotoSize::Large)].location.height();
|
||||
}
|
||||
|
||||
bool PhotoData::hasVideo() const {
|
||||
return _video.location.valid();
|
||||
}
|
||||
|
||||
bool PhotoData::videoLoading() const {
|
||||
return _video.loader != nullptr;
|
||||
}
|
||||
|
||||
bool PhotoData::videoFailed() const {
|
||||
return (_video.flags & Data::CloudFile::Flag::Failed);
|
||||
}
|
||||
|
||||
void PhotoData::loadVideo(Data::FileOrigin origin) {
|
||||
const auto autoLoading = false;
|
||||
const auto finalCheck = [=] {
|
||||
if (const auto active = activeMediaView()) {
|
||||
return active->videoContent().isEmpty();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
const auto done = [=](QByteArray result) {
|
||||
if (const auto active = activeMediaView()) {
|
||||
active->setVideo(std::move(result));
|
||||
}
|
||||
};
|
||||
Data::LoadCloudFile(
|
||||
&session(),
|
||||
_video,
|
||||
origin,
|
||||
LoadFromCloudOrLocal,
|
||||
autoLoading,
|
||||
Data::kAnimationCacheTag,
|
||||
finalCheck,
|
||||
done);
|
||||
}
|
||||
|
||||
const ImageLocation &PhotoData::videoLocation() const {
|
||||
return _video.location;
|
||||
}
|
||||
|
||||
int PhotoData::videoByteSize() const {
|
||||
return _video.byteSize;
|
||||
}
|
||||
|
||||
PhotoClickHandler::PhotoClickHandler(
|
||||
not_null<PhotoData*> photo,
|
||||
FullMsgId context,
|
||||
|
|
|
@ -82,7 +82,8 @@ public:
|
|||
const QByteArray &inlineThumbnailBytes,
|
||||
const ImageWithLocation &small,
|
||||
const ImageWithLocation &thumbnail,
|
||||
const ImageWithLocation &large);
|
||||
const ImageWithLocation &large,
|
||||
const ImageWithLocation &video);
|
||||
[[nodiscard]] int validSizeIndex(Data::PhotoSize size) const;
|
||||
|
||||
[[nodiscard]] QByteArray inlineThumbnailBytes() const {
|
||||
|
@ -111,6 +112,13 @@ public:
|
|||
[[nodiscard]] std::optional<QSize> size(Data::PhotoSize size) const;
|
||||
[[nodiscard]] int imageByteSize(Data::PhotoSize size) const;
|
||||
|
||||
[[nodiscard]] bool hasVideo() const;
|
||||
[[nodiscard]] bool videoLoading() const;
|
||||
[[nodiscard]] bool videoFailed() const;
|
||||
void loadVideo(Data::FileOrigin origin);
|
||||
[[nodiscard]] const ImageLocation &videoLocation() const;
|
||||
[[nodiscard]] int videoByteSize() const;
|
||||
|
||||
// For now they return size of the 'large' image.
|
||||
int width() const;
|
||||
int height() const;
|
||||
|
@ -127,6 +135,7 @@ public:
|
|||
private:
|
||||
QByteArray _inlineThumbnailBytes;
|
||||
std::array<Data::CloudFile, Data::kPhotoSizeCount> _images;
|
||||
Data::CloudFile _video;
|
||||
|
||||
int32 _dc = 0;
|
||||
uint64 _access = 0;
|
||||
|
|
|
@ -85,6 +85,25 @@ void PhotoMedia::set(PhotoSize size, QImage image) {
|
|||
_owner->session().notifyDownloaderTaskFinished();
|
||||
}
|
||||
|
||||
QByteArray PhotoMedia::videoContent() const {
|
||||
return _videoBytes;
|
||||
}
|
||||
|
||||
QSize PhotoMedia::videoSize() const {
|
||||
const auto &location = _owner->videoLocation();
|
||||
return { location.width(), location.height() };
|
||||
}
|
||||
|
||||
void PhotoMedia::videoWanted(Data::FileOrigin origin) {
|
||||
if (_videoBytes.isEmpty()) {
|
||||
_owner->loadVideo(origin);
|
||||
}
|
||||
}
|
||||
|
||||
void PhotoMedia::setVideo(QByteArray content) {
|
||||
_videoBytes = std::move(content);
|
||||
}
|
||||
|
||||
bool PhotoMedia::loaded() const {
|
||||
const auto index = PhotoSizeIndex(PhotoSize::Large);
|
||||
return (_images[index] != nullptr);
|
||||
|
|
|
@ -28,6 +28,11 @@ public:
|
|||
void wanted(PhotoSize size, Data::FileOrigin origin);
|
||||
void set(PhotoSize size, QImage image);
|
||||
|
||||
[[nodiscard]] QByteArray videoContent() const;
|
||||
[[nodiscard]] QSize videoSize() const;
|
||||
void videoWanted(Data::FileOrigin origin);
|
||||
void setVideo(QByteArray content);
|
||||
|
||||
[[nodiscard]] bool loaded() const;
|
||||
[[nodiscard]] float64 progress() const;
|
||||
|
||||
|
@ -42,6 +47,7 @@ private:
|
|||
const not_null<PhotoData*> _owner;
|
||||
mutable std::unique_ptr<Image> _inlineThumbnail;
|
||||
std::array<std::unique_ptr<Image>, kPhotoSizeCount> _images;
|
||||
QByteArray _videoBytes;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -2157,7 +2157,8 @@ not_null<PhotoData*> Session::processPhoto(
|
|||
QByteArray(),
|
||||
small,
|
||||
thumbnail,
|
||||
large);
|
||||
large,
|
||||
ImageWithLocation{});
|
||||
}, [&](const MTPDphotoEmpty &data) {
|
||||
return photo(data.vid().v);
|
||||
});
|
||||
|
@ -2173,7 +2174,8 @@ not_null<PhotoData*> Session::photo(
|
|||
const QByteArray &inlineThumbnailBytes,
|
||||
const ImageWithLocation &small,
|
||||
const ImageWithLocation &thumbnail,
|
||||
const ImageWithLocation &large) {
|
||||
const ImageWithLocation &large,
|
||||
const ImageWithLocation &video) {
|
||||
const auto result = photo(id);
|
||||
photoApplyFields(
|
||||
result,
|
||||
|
@ -2185,7 +2187,8 @@ not_null<PhotoData*> Session::photo(
|
|||
inlineThumbnailBytes,
|
||||
small,
|
||||
thumbnail,
|
||||
large);
|
||||
large,
|
||||
video);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2233,7 +2236,8 @@ PhotoData *Session::photoFromWeb(
|
|||
QByteArray(),
|
||||
ImageWithLocation{},
|
||||
ImageWithLocation{ .location = thumbnailLocation },
|
||||
ImageWithLocation{ .location = large });
|
||||
ImageWithLocation{ .location = large },
|
||||
ImageWithLocation{});
|
||||
}
|
||||
|
||||
void Session::photoApplyFields(
|
||||
|
@ -2271,6 +2275,22 @@ void Session::photoApplyFields(
|
|||
? ImageWithLocation()
|
||||
: Images::FromPhotoSize(_session, data, *i);
|
||||
};
|
||||
const auto video = [&] {
|
||||
const auto sizes = data.vvideo_sizes();
|
||||
if (!sizes || sizes->v.isEmpty()) {
|
||||
return ImageWithLocation();
|
||||
}
|
||||
const auto area = [](const MTPVideoSize &size) {
|
||||
return size.match([](const MTPDvideoSize &data) {
|
||||
return data.vw().v * data.vh().v;
|
||||
});
|
||||
};
|
||||
const auto max = ranges::max_element(
|
||||
sizes->v,
|
||||
std::greater<>(),
|
||||
area);
|
||||
return Images::FromVideoSize(_session, data, *max);
|
||||
};
|
||||
const auto large = image(LargeLevels);
|
||||
if (large.location.valid()) {
|
||||
photoApplyFields(
|
||||
|
@ -2283,7 +2303,8 @@ void Session::photoApplyFields(
|
|||
FindPhotoInlineThumbnail(data),
|
||||
image(SmallLevels),
|
||||
image(ThumbnailLevels),
|
||||
large);
|
||||
large,
|
||||
video());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2297,7 +2318,8 @@ void Session::photoApplyFields(
|
|||
const QByteArray &inlineThumbnailBytes,
|
||||
const ImageWithLocation &small,
|
||||
const ImageWithLocation &thumbnail,
|
||||
const ImageWithLocation &large) {
|
||||
const ImageWithLocation &large,
|
||||
const ImageWithLocation &video) {
|
||||
if (!date) {
|
||||
return;
|
||||
}
|
||||
|
@ -2308,7 +2330,8 @@ void Session::photoApplyFields(
|
|||
inlineThumbnailBytes,
|
||||
small,
|
||||
thumbnail,
|
||||
large);
|
||||
large,
|
||||
video);
|
||||
}
|
||||
|
||||
not_null<DocumentData*> Session::document(DocumentId id) {
|
||||
|
|
|
@ -403,7 +403,8 @@ public:
|
|||
const QByteArray &inlineThumbnailBytes,
|
||||
const ImageWithLocation &small,
|
||||
const ImageWithLocation &thumbnail,
|
||||
const ImageWithLocation &large);
|
||||
const ImageWithLocation &large,
|
||||
const ImageWithLocation &video);
|
||||
void photoConvert(
|
||||
not_null<PhotoData*> original,
|
||||
const MTPPhoto &data);
|
||||
|
@ -671,7 +672,8 @@ private:
|
|||
const QByteArray &inlineThumbnailBytes,
|
||||
const ImageWithLocation &small,
|
||||
const ImageWithLocation &thumbnail,
|
||||
const ImageWithLocation &large);
|
||||
const ImageWithLocation &large,
|
||||
const ImageWithLocation &video);
|
||||
|
||||
void documentApplyFields(
|
||||
not_null<DocumentData*> document,
|
||||
|
|
|
@ -268,4 +268,26 @@ ImageWithLocation FromVideoSize(
|
|||
});
|
||||
}
|
||||
|
||||
ImageWithLocation FromVideoSize(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPDphoto &photo,
|
||||
const MTPVideoSize &size) {
|
||||
return size.match([&](const MTPDvideoSize &data) {
|
||||
return ImageWithLocation{
|
||||
.location = ImageLocation(
|
||||
DownloadLocation{ StorageFileLocation(
|
||||
photo.vdc_id().v,
|
||||
session->userId(),
|
||||
MTP_inputPhotoFileLocation(
|
||||
photo.vid(),
|
||||
photo.vaccess_hash(),
|
||||
photo.vfile_reference(),
|
||||
data.vtype())) },
|
||||
data.vw().v,
|
||||
data.vh().v),
|
||||
.bytesCount = data.vsize().v
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Images
|
||||
|
|
|
@ -31,6 +31,10 @@ namespace Images {
|
|||
not_null<Main::Session*> session,
|
||||
const MTPDdocument &document,
|
||||
const MTPVideoSize &size);
|
||||
[[nodiscard]] ImageWithLocation FromVideoSize(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPDphoto &photo,
|
||||
const MTPVideoSize &size);
|
||||
[[nodiscard]] ImageWithLocation FromImageInMemory(
|
||||
const QImage &image,
|
||||
const char *format);
|
||||
|
|
Loading…
Add table
Reference in a new issue