147 lines
4.1 KiB
C++
147 lines
4.1 KiB
C++
/*
|
|
This file is part of Telegram Desktop,
|
|
the official desktop application for the Telegram messaging service.
|
|
|
|
For license and copyright information please follow this link:
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
*/
|
|
#include "data/data_reply_preview.h"
|
|
|
|
#include "data/data_file_origin.h"
|
|
#include "data/data_document.h"
|
|
#include "data/data_document_media.h"
|
|
#include "data/data_photo.h"
|
|
#include "data/data_photo_media.h"
|
|
#include "ui/image/image.h"
|
|
#include "styles/style_chat.h"
|
|
|
|
namespace Data {
|
|
|
|
ReplyPreview::ReplyPreview(not_null<DocumentData*> document)
|
|
: _document(document) {
|
|
}
|
|
|
|
ReplyPreview::ReplyPreview(not_null<PhotoData*> photo)
|
|
: _photo(photo) {
|
|
}
|
|
|
|
ReplyPreview::~ReplyPreview() = default;
|
|
|
|
void ReplyPreview::prepare(
|
|
not_null<Image*> image,
|
|
Images::Options options,
|
|
bool spoiler) {
|
|
using namespace Images;
|
|
if (image->isNull()) {
|
|
return;
|
|
}
|
|
int w = image->width(), h = image->height();
|
|
if (w <= 0) w = 1;
|
|
if (h <= 0) h = 1;
|
|
auto thumbSize = (w > h)
|
|
? QSize(
|
|
w * st::msgReplyBarSize.height() / h,
|
|
st::msgReplyBarSize.height())
|
|
: QSize(
|
|
st::msgReplyBarSize.height(),
|
|
h * st::msgReplyBarSize.height() / w);
|
|
thumbSize *= style::DevicePixelRatio();
|
|
options |= Option::TransparentBackground;
|
|
auto outerSize = st::msgReplyBarSize.height();
|
|
auto original = spoiler
|
|
? image->original().scaled(
|
|
{ 40, 40 },
|
|
Qt::KeepAspectRatio,
|
|
Qt::SmoothTransformation)
|
|
: image->original();
|
|
auto prepared = Prepare(std::move(original), thumbSize, {
|
|
.options = options | (spoiler ? Option::Blur : Option()),
|
|
.outer = { outerSize, outerSize },
|
|
});
|
|
(spoiler ? _spoilered : _regular) = std::make_unique<Image>(
|
|
std::move(prepared));
|
|
_good = spoiler || ((options & Option::Blur) == 0);
|
|
}
|
|
|
|
Image *ReplyPreview::image(
|
|
Data::FileOrigin origin,
|
|
not_null<PeerData*> context,
|
|
bool spoiler) {
|
|
auto &image = spoiler ? _spoilered : _regular;
|
|
auto &checked = spoiler ? _checkedSpoilered : _checkedRegular;
|
|
if (checked) {
|
|
return image.get();
|
|
} else if (_document) {
|
|
if (!image || (!_good && _document->hasThumbnail())) {
|
|
if (!_documentMedia) {
|
|
_documentMedia = _document->createMediaView();
|
|
_documentMedia->thumbnailWanted(origin);
|
|
}
|
|
const auto thumbnail = _documentMedia->thumbnail();
|
|
const auto option = _document->isVideoMessage()
|
|
? Images::Option::RoundCircle
|
|
: Images::Option::None;
|
|
if (spoiler) {
|
|
if (const auto image = _documentMedia->thumbnailInline()) {
|
|
prepare(image, option, true);
|
|
} else if (thumbnail) {
|
|
prepare(thumbnail, option, true);
|
|
}
|
|
} else if (thumbnail) {
|
|
prepare(thumbnail, option);
|
|
} else if (!image) {
|
|
if (const auto image = _documentMedia->thumbnailInline()) {
|
|
prepare(image, option | Images::Option::Blur);
|
|
}
|
|
}
|
|
if (_good || !_document->hasThumbnail()) {
|
|
checked = true;
|
|
_documentMedia = nullptr;
|
|
}
|
|
}
|
|
} else {
|
|
Assert(_photo != nullptr);
|
|
if (!image || !_good) {
|
|
const auto inlineThumbnailBytes = _photo->inlineThumbnailBytes();
|
|
if (!_photoMedia) {
|
|
_photoMedia = _photo->createMediaView();
|
|
}
|
|
using Size = PhotoSize;
|
|
const auto loadThumbnail = inlineThumbnailBytes.isEmpty()
|
|
|| (!spoiler
|
|
&& _photoMedia->autoLoadThumbnailAllowed(context));
|
|
if (loadThumbnail) {
|
|
_photoMedia->wanted(Size::Small, origin);
|
|
}
|
|
if (spoiler) {
|
|
if (const auto blurred = _photoMedia->thumbnailInline()) {
|
|
prepare(blurred, {}, true);
|
|
} else if (const auto small = _photoMedia->image(Size::Small)) {
|
|
prepare(small, {}, true);
|
|
} else if (const auto large = _photoMedia->image(Size::Large)) {
|
|
prepare(large, {}, true);
|
|
}
|
|
} else if (const auto small = _photoMedia->image(Size::Small)) {
|
|
prepare(small, {});
|
|
} else if (const auto large = _photoMedia->image(Size::Large)) {
|
|
prepare(large, {});
|
|
} else if (!image) {
|
|
if (const auto blurred = _photoMedia->thumbnailInline()) {
|
|
prepare(blurred, Images::Option::Blur);
|
|
}
|
|
}
|
|
if (_good) {
|
|
checked = true;
|
|
_photoMedia = nullptr;
|
|
}
|
|
}
|
|
}
|
|
return image.get();
|
|
}
|
|
|
|
bool ReplyPreview::loaded(bool spoiler) const {
|
|
return spoiler ? _checkedSpoilered : _checkedRegular;
|
|
}
|
|
|
|
} // namespace Data
|