mirror of
https://github.com/telegramdesktop/tdesktop
synced 2024-12-14 18:34:49 +00:00
Start DocumentData::thumbnail move to DocumentMedia.
This commit is contained in:
parent
1329870c8e
commit
956c3af0ae
@ -16,6 +16,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "mtproto/sender.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_document_media.h"
|
||||
#include "boxes/background_preview_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "app.h"
|
||||
@ -75,6 +77,7 @@ protected:
|
||||
private:
|
||||
struct Paper {
|
||||
Data::WallPaper data;
|
||||
mutable std::shared_ptr<Data::DocumentMedia> dataMedia;
|
||||
mutable QPixmap thumbnail;
|
||||
};
|
||||
struct Selected {
|
||||
@ -252,11 +255,21 @@ void BackgroundBox::Inner::resizeToContentAndPreload() {
|
||||
const auto rows = (count / kBackgroundsInRow)
|
||||
+ (count % kBackgroundsInRow ? 1 : 0);
|
||||
|
||||
resize(st::boxWideWidth, rows * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding);
|
||||
resize(
|
||||
st::boxWideWidth,
|
||||
(rows * (st::backgroundSize.height() + st::backgroundPadding)
|
||||
+ st::backgroundPadding));
|
||||
|
||||
const auto preload = kBackgroundsInRow * 3;
|
||||
for (const auto &paper : _papers | ranges::view::take(preload)) {
|
||||
paper.data.loadThumbnail();
|
||||
if (paper.data.localThumbnail()) {
|
||||
paper.data.loadLocalThumbnail();
|
||||
} else if (const auto document = paper.data.document()) {
|
||||
if (!paper.dataMedia) {
|
||||
paper.dataMedia = document->createMediaView();
|
||||
paper.dataMedia->thumbnailWanted(paper.data.fileOrigin());
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
@ -292,15 +305,27 @@ void BackgroundBox::Inner::paintEvent(QPaintEvent *e) {
|
||||
|
||||
void BackgroundBox::Inner::validatePaperThumbnail(
|
||||
const Paper &paper) const {
|
||||
Expects(paper.data.thumbnail() != nullptr);
|
||||
|
||||
const auto thumbnail = paper.data.thumbnail();
|
||||
if (!paper.thumbnail.isNull()) {
|
||||
return;
|
||||
} else if (!thumbnail->loaded()) {
|
||||
thumbnail->load(paper.data.fileOrigin());
|
||||
}
|
||||
const auto localThumbnail = paper.data.localThumbnail();
|
||||
if (!localThumbnail) {
|
||||
if (const auto document = paper.data.document()) {
|
||||
if (!paper.dataMedia) {
|
||||
paper.dataMedia = document->createMediaView();
|
||||
paper.dataMedia->thumbnailWanted(paper.data.fileOrigin());
|
||||
}
|
||||
}
|
||||
if (!paper.dataMedia || !paper.dataMedia->thumbnail()) {
|
||||
return;
|
||||
}
|
||||
} else if (!localThumbnail->loaded()) {
|
||||
localThumbnail->load(paper.data.fileOrigin());
|
||||
return;
|
||||
}
|
||||
const auto thumbnail = localThumbnail
|
||||
? localThumbnail
|
||||
: paper.dataMedia->thumbnail();
|
||||
auto original = thumbnail->original();
|
||||
if (paper.data.isPattern()) {
|
||||
const auto color = *paper.data.backgroundColor();
|
||||
@ -314,6 +339,7 @@ void BackgroundBox::Inner::validatePaperThumbnail(
|
||||
original,
|
||||
st::backgroundSize));
|
||||
paper.thumbnail.setDevicePixelRatio(cRetinaFactor());
|
||||
paper.dataMedia = nullptr;
|
||||
}
|
||||
|
||||
void BackgroundBox::Inner::paintPaper(
|
||||
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_document_media.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/background_preview_box.h"
|
||||
@ -413,6 +414,9 @@ BackgroundPreviewBox::BackgroundPreviewBox(
|
||||
, _paper(paper)
|
||||
, _media(_paper.document() ? _paper.document()->createMediaView() : nullptr)
|
||||
, _radial([=](crl::time now) { radialAnimationCallback(now); }) {
|
||||
if (_media) {
|
||||
_media->thumbnailWanted(_paper.fileOrigin());
|
||||
}
|
||||
subscribe(_session->downloaderTaskFinished(), [=] { update(); });
|
||||
}
|
||||
|
||||
@ -430,12 +434,15 @@ void BackgroundPreviewBox::prepare() {
|
||||
}
|
||||
updateServiceBg(_paper.backgroundColor());
|
||||
|
||||
_paper.loadThumbnail();
|
||||
_paper.loadLocalThumbnail();
|
||||
_paper.loadDocument();
|
||||
if (_paper.document() && _paper.document()->loading()) {
|
||||
const auto document = _paper.document();
|
||||
if (document && document->loading()) {
|
||||
_radial.start(_media->progress());
|
||||
}
|
||||
if (_paper.thumbnail() && !_paper.isPattern()) {
|
||||
if (!_paper.isPattern()
|
||||
&& (_paper.localThumbnail()
|
||||
|| (document && document->hasThumbnail()))) {
|
||||
createBlurCheckbox();
|
||||
}
|
||||
setScaledFromThumb();
|
||||
@ -647,7 +654,12 @@ void BackgroundPreviewBox::radialAnimationCallback(crl::time now) {
|
||||
}
|
||||
|
||||
bool BackgroundPreviewBox::setScaledFromThumb() {
|
||||
const auto thumbnail = _paper.thumbnail();
|
||||
const auto localThumbnail = _paper.localThumbnail();
|
||||
const auto thumbnail = localThumbnail
|
||||
? localThumbnail
|
||||
: _media
|
||||
? _media->thumbnail()
|
||||
: nullptr;
|
||||
if (!thumbnail || !thumbnail->loaded()) {
|
||||
return false;
|
||||
} else if (_paper.isPattern() && _paper.document() != nullptr) {
|
||||
|
@ -61,7 +61,6 @@ EditCaptionBox::EditCaptionBox(
|
||||
|
||||
QSize dimensions;
|
||||
auto image = (Image*)nullptr;
|
||||
DocumentData *doc = nullptr;
|
||||
|
||||
const auto media = item->media();
|
||||
if (const auto photo = media->photo()) {
|
||||
@ -69,7 +68,10 @@ EditCaptionBox::EditCaptionBox(
|
||||
dimensions = QSize(photo->width(), photo->height());
|
||||
image = photo->large();
|
||||
} else if (const auto document = media->document()) {
|
||||
image = document->thumbnail();
|
||||
_documentMedia = document->createMediaView();
|
||||
_documentMedia->thumbnailWanted(_msgId);
|
||||
// #TODO optimize + streamed GIF view
|
||||
image = _documentMedia->thumbnail();
|
||||
dimensions = image
|
||||
? image->size()
|
||||
: document->dimensions;
|
||||
@ -82,11 +84,10 @@ EditCaptionBox::EditCaptionBox(
|
||||
} else {
|
||||
_doc = true;
|
||||
}
|
||||
doc = document;
|
||||
}
|
||||
const auto editData = PrepareEditText(item);
|
||||
|
||||
if (!_animated && (dimensions.isEmpty() || doc || !image)) {
|
||||
if (!_animated && (dimensions.isEmpty() || _documentMedia || !image)) {
|
||||
if (!image) {
|
||||
_thumbw = 0;
|
||||
} else {
|
||||
@ -114,13 +115,15 @@ EditCaptionBox::EditCaptionBox(
|
||||
};
|
||||
}
|
||||
|
||||
if (doc) {
|
||||
const auto nameString = doc->isVoiceMessage()
|
||||
if (_documentMedia) {
|
||||
const auto document = _documentMedia->owner();
|
||||
const auto nameString = document->isVoiceMessage()
|
||||
? tr::lng_media_audio(tr::now)
|
||||
: doc->composeNameString();
|
||||
setName(nameString, doc->size);
|
||||
_isImage = doc->isImage();
|
||||
_isAudio = (doc->isVoiceMessage() || doc->isAudioFile());
|
||||
: document->composeNameString();
|
||||
setName(nameString, document->size);
|
||||
_isImage = document->isImage();
|
||||
_isAudio = document->isVoiceMessage()
|
||||
|| document->isAudioFile();
|
||||
}
|
||||
if (_refreshThumbnail) {
|
||||
_refreshThumbnail();
|
||||
@ -158,10 +161,7 @@ EditCaptionBox::EditCaptionBox(
|
||||
maxW,
|
||||
maxH);
|
||||
};
|
||||
if (doc) {
|
||||
_gifMedia = doc->createMediaView();
|
||||
}
|
||||
prepareGifPreview(doc);
|
||||
prepareGifPreview();
|
||||
} else {
|
||||
maxW = dimensions.width();
|
||||
maxH = dimensions.height();
|
||||
@ -209,7 +209,7 @@ EditCaptionBox::EditCaptionBox(
|
||||
thumbX = (st::boxWideWidth - thumbWidth) / 2;
|
||||
};
|
||||
|
||||
if (doc && doc->isAnimation()) {
|
||||
if (_documentMedia && _documentMedia->owner()->isAnimation()) {
|
||||
resizeDimensions(_gifw, _gifh, _gifx);
|
||||
}
|
||||
limitH = std::min(st::confirmMaxHeight, _gifh ? _gifh : INT_MAX);
|
||||
@ -252,12 +252,9 @@ EditCaptionBox::EditCaptionBox(
|
||||
_refreshThumbnail();
|
||||
update();
|
||||
}
|
||||
if (doc && doc->isAnimation()) {
|
||||
if (!_gifMedia) {
|
||||
_gifMedia = doc->createMediaView();
|
||||
}
|
||||
if (_gifMedia->loaded() && !_gifPreview) {
|
||||
prepareGifPreview(doc);
|
||||
if (_documentMedia && _documentMedia->owner()->isAnimation()) {
|
||||
if (_documentMedia->loaded() && !_gifPreview) {
|
||||
prepareGifPreview();
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -314,23 +311,23 @@ void EditCaptionBox::updateEmojiPanelGeometry() {
|
||||
local.x() + _emojiToggle->width() * 3);
|
||||
}
|
||||
|
||||
void EditCaptionBox::prepareGifPreview(DocumentData* document) {
|
||||
Expects(!document || (_gifMedia != nullptr));
|
||||
|
||||
void EditCaptionBox::prepareGifPreview() {
|
||||
const auto isListEmpty = _preparedList.files.empty();
|
||||
if (_gifPreview) {
|
||||
return;
|
||||
} else if (!document && isListEmpty) {
|
||||
} else if (!_documentMedia && isListEmpty) {
|
||||
return;
|
||||
}
|
||||
const auto callback = [=](Media::Clip::Notification notification) {
|
||||
clipCallback(notification);
|
||||
};
|
||||
if (document && document->isAnimation() && _gifMedia->loaded()) {
|
||||
_gifPreview = Media::Clip::MakeReader(
|
||||
_gifMedia.get(),
|
||||
_msgId,
|
||||
callback);
|
||||
if (_documentMedia && _documentMedia->owner()->isAnimation()) {
|
||||
if (_documentMedia->loaded()) {
|
||||
_gifPreview = Media::Clip::MakeReader(
|
||||
_documentMedia.get(),
|
||||
_msgId,
|
||||
callback);
|
||||
}
|
||||
} else if (!isListEmpty) {
|
||||
const auto file = &_preparedList.files.front();
|
||||
if (file->path.isEmpty()) {
|
||||
@ -343,7 +340,9 @@ void EditCaptionBox::prepareGifPreview(DocumentData* document) {
|
||||
callback);
|
||||
}
|
||||
}
|
||||
if (_gifPreview) _gifPreview->setAutoplay();
|
||||
if (_gifPreview) {
|
||||
_gifPreview->setAutoplay();
|
||||
}
|
||||
}
|
||||
|
||||
void EditCaptionBox::clipCallback(Media::Clip::Notification notification) {
|
||||
|
@ -57,7 +57,7 @@ protected:
|
||||
|
||||
private:
|
||||
void updateBoxSize();
|
||||
void prepareGifPreview(DocumentData* document = nullptr);
|
||||
void prepareGifPreview();
|
||||
void clipCallback(Media::Clip::Notification notification);
|
||||
|
||||
void setupEmojiPanel();
|
||||
@ -87,6 +87,7 @@ private:
|
||||
|
||||
not_null<Window::SessionController*> _controller;
|
||||
FullMsgId _msgId;
|
||||
std::shared_ptr<Data::DocumentMedia> _documentMedia;
|
||||
Image *_thumbnailImage = nullptr;
|
||||
bool _thumbnailImageLoaded = false;
|
||||
Fn<void()> _refreshThumbnail;
|
||||
@ -95,7 +96,6 @@ private:
|
||||
bool _doc = false;
|
||||
|
||||
QPixmap _thumb;
|
||||
std::shared_ptr<Data::DocumentMedia> _gifMedia;
|
||||
Media::Clip::ReaderPointer _gifPreview;
|
||||
|
||||
object_ptr<Ui::InputField> _field = { nullptr };
|
||||
|
@ -908,7 +908,7 @@ void StickersBox::Inner::paintRowThumbnail(
|
||||
set->accessHash);
|
||||
const auto thumb = set->thumbnail
|
||||
? set->thumbnail.get()
|
||||
: set->sticker->thumbnail();
|
||||
: set->stickerMedia->thumbnail();
|
||||
if (!thumb) {
|
||||
return;
|
||||
}
|
||||
@ -1650,6 +1650,8 @@ void StickersBox::Inner::updateRows() {
|
||||
row->thumbnail = thumbnail;
|
||||
row->sticker = sticker;
|
||||
row->stickerMedia = sticker->createMediaView();
|
||||
row->stickerMedia->thumbnailWanted(
|
||||
Data::FileOriginStickerSet(row->id, row->accessHash));
|
||||
row->pixw = pixw;
|
||||
row->pixh = pixh;
|
||||
}
|
||||
@ -1747,8 +1749,10 @@ void StickersBox::Inner::fillSetCover(const Stickers::Set &set, ImagePtr *thumbn
|
||||
|
||||
const auto size = set.thumbnail
|
||||
? set.thumbnail->size()
|
||||
: sticker->thumbnail()
|
||||
? sticker->thumbnail()->size()
|
||||
: sticker->hasThumbnail()
|
||||
? QSize(
|
||||
sticker->thumbnailLocation().width(),
|
||||
sticker->thumbnailLocation().height())
|
||||
: QSize(1, 1);
|
||||
auto pixw = size.width();
|
||||
auto pixh = size.height();
|
||||
@ -1913,10 +1917,17 @@ void StickersBox::Inner::readVisibleSets() {
|
||||
? nullptr
|
||||
: _rows[i]->thumbnail
|
||||
? _rows[i]->thumbnail.get()
|
||||
: _rows[i]->sticker->thumbnail();
|
||||
if (!thumbnail
|
||||
|| thumbnail->loaded()
|
||||
|| _rows[i]->stickerMedia->loaded()) {
|
||||
: _rows[i]->stickerMedia
|
||||
? _rows[i]->stickerMedia->thumbnail()
|
||||
: nullptr;
|
||||
const auto thumbnailLoading = !_rows[i]->sticker
|
||||
? false
|
||||
: _rows[i]->thumbnail
|
||||
? !thumbnail->loaded()
|
||||
: _rows[i]->stickerMedia
|
||||
? _rows[i]->sticker->thumbnailLoading()
|
||||
: false;
|
||||
if (!thumbnailLoading || _rows[i]->stickerMedia->loaded()) {
|
||||
_session->api().readFeaturedSetDelayed(_rows[i]->id);
|
||||
}
|
||||
}
|
||||
|
@ -748,7 +748,7 @@ void StickersListWidget::Footer::paintSetIcon(
|
||||
const auto origin = icon.sticker->stickerSetOrigin();
|
||||
const auto thumb = icon.thumbnail
|
||||
? icon.thumbnail.get()
|
||||
: icon.sticker->thumbnail();
|
||||
: icon.stickerMedia->thumbnail();
|
||||
if (!thumb) {
|
||||
return;
|
||||
}
|
||||
@ -988,7 +988,7 @@ void StickersListWidget::readVisibleFeatured(
|
||||
int loaded = 0;
|
||||
for (int j = 0; j < count; ++j) {
|
||||
if (!set.stickers[j].document->hasThumbnail()
|
||||
|| set.stickers[j].document->thumbnail()->loaded()
|
||||
|| !set.stickers[j].document->thumbnailLoading()
|
||||
|| set.stickers[j].documentMedia->loaded()) {
|
||||
++loaded;
|
||||
}
|
||||
@ -2602,7 +2602,9 @@ void StickersListWidget::fillIcons(QList<StickerIcon> &icons) {
|
||||
const auto size = thumbnail
|
||||
? thumbnail->size()
|
||||
: s->hasThumbnail()
|
||||
? s->thumbnail()->size()
|
||||
? QSize(
|
||||
s->thumbnailLocation().width(),
|
||||
s->thumbnailLocation().height())
|
||||
: QSize();
|
||||
auto thumbw = size.width(), thumbh = size.height(), pixw = 1, pixh = 1;
|
||||
if (availw * thumbh > availh * thumbw) {
|
||||
|
@ -452,6 +452,7 @@ DocumentData::DocumentData(not_null<Data::Session*> owner, DocumentId id)
|
||||
}
|
||||
|
||||
DocumentData::~DocumentData() {
|
||||
base::take(_thumbnailLoader).reset();
|
||||
destroyLoader();
|
||||
unload();
|
||||
}
|
||||
@ -564,7 +565,7 @@ void DocumentData::setattributes(
|
||||
void DocumentData::validateLottieSticker() {
|
||||
if (type == FileDocument
|
||||
&& _mimeString == qstr("application/x-tgsticker")
|
||||
&& _thumbnail) {
|
||||
&& hasThumbnail()) {
|
||||
type = StickerDocument;
|
||||
_additional = std::make_unique<StickerData>();
|
||||
sticker()->animated = true;
|
||||
@ -590,7 +591,7 @@ bool DocumentData::checkWallPaperProperties() {
|
||||
return true;
|
||||
}
|
||||
if (type != FileDocument
|
||||
|| !_thumbnail
|
||||
|| !hasThumbnail()
|
||||
|| !dimensions.width()
|
||||
|| !dimensions.height()
|
||||
|| dimensions.width() > Storage::kMaxWallPaperDimension
|
||||
@ -605,20 +606,28 @@ bool DocumentData::checkWallPaperProperties() {
|
||||
|
||||
void DocumentData::updateThumbnails(
|
||||
const QByteArray &inlineThumbnailBytes,
|
||||
ImagePtr thumbnail) {
|
||||
const StorageImageLocation &thumbnail) {
|
||||
if (!inlineThumbnailBytes.isEmpty()
|
||||
&& _inlineThumbnailBytes.isEmpty()) {
|
||||
_inlineThumbnailBytes = inlineThumbnailBytes;
|
||||
}
|
||||
if (thumbnail
|
||||
&& (!_thumbnail
|
||||
|| (sticker()
|
||||
&& (_thumbnail->width() < thumbnail->width()
|
||||
|| _thumbnail->height() < thumbnail->height())))) {
|
||||
_thumbnail = thumbnail;
|
||||
if (thumbnail.valid()
|
||||
&& (!_thumbnailLocation.valid()
|
||||
|| _thumbnailLocation.width() < thumbnail.width()
|
||||
|| _thumbnailLocation.height() < thumbnail.height())) {
|
||||
_thumbnailLocation = thumbnail;
|
||||
if (_thumbnailLoader) {
|
||||
const auto origin = base::take(_thumbnailLoader)->fileOrigin();
|
||||
loadThumbnail(origin);
|
||||
// #TODO optimize replace thumbnail in activeMediaView().
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const StorageImageLocation &DocumentData::thumbnailLocation() const {
|
||||
return _thumbnailLocation;
|
||||
}
|
||||
|
||||
bool DocumentData::isWallPaper() const {
|
||||
return (type == WallPaperDocument);
|
||||
}
|
||||
@ -628,17 +637,53 @@ bool DocumentData::isPatternWallPaper() const {
|
||||
}
|
||||
|
||||
bool DocumentData::hasThumbnail() const {
|
||||
return !_thumbnail->isNull();
|
||||
return _thumbnailLocation.valid()
|
||||
&& (_thumbnailLocation.width() > 0)
|
||||
&& (_thumbnailLocation.height() > 0);
|
||||
}
|
||||
|
||||
Image *DocumentData::thumbnail() const {
|
||||
return _thumbnail ? _thumbnail.get() : nullptr;
|
||||
bool DocumentData::thumbnailLoading() const {
|
||||
return _thumbnailLoader != nullptr;
|
||||
}
|
||||
|
||||
bool DocumentData::thumbnailFailed() const {
|
||||
return (_flags & Flag::ThumbnailFailed);
|
||||
}
|
||||
|
||||
void DocumentData::loadThumbnail(Data::FileOrigin origin) {
|
||||
if (_thumbnail && !_thumbnail->loaded()) {
|
||||
_thumbnail->load(origin);
|
||||
if (_thumbnailLoader || (_flags & Flag::ThumbnailFailed)) {
|
||||
return;
|
||||
} else if (const auto active = activeMediaView()) {
|
||||
if (active->thumbnail()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const auto autoLoading = false;
|
||||
_thumbnailLoader = std::make_unique<mtpFileLoader>(
|
||||
_thumbnailLocation.file(),
|
||||
origin,
|
||||
UnknownFileLocation,
|
||||
QString(),
|
||||
_thumbnailSize,
|
||||
LoadToCacheAsWell,
|
||||
LoadFromCloudOrLocal,
|
||||
autoLoading,
|
||||
Data::kImageCacheTag);
|
||||
_thumbnailLoader->updates(
|
||||
) | rpl::start_with_error_done([=](bool started) {
|
||||
_thumbnailLoader = nullptr;
|
||||
_flags |= Flag::ThumbnailFailed;
|
||||
}, [=] {
|
||||
if (!_thumbnailLoader->cancelled()) {
|
||||
if (auto image = _thumbnailLoader->imageData(); image.isNull()) {
|
||||
_flags |= Flag::ThumbnailFailed;
|
||||
} else if (const auto active = activeMediaView()) {
|
||||
active->setThumbnail(std::move(image));
|
||||
}
|
||||
}
|
||||
_thumbnailLoader = nullptr;
|
||||
}) | rpl::release();
|
||||
_thumbnailLoader->start();
|
||||
}
|
||||
|
||||
Storage::Cache::Key DocumentData::goodThumbnailCacheKey() const {
|
||||
@ -765,7 +810,7 @@ void DocumentData::finishLoad() {
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentData::destroyLoader() const {
|
||||
void DocumentData::destroyLoader() {
|
||||
if (!_loader) {
|
||||
return;
|
||||
}
|
||||
@ -1140,7 +1185,7 @@ bool DocumentData::isStickerSetInstalled() const {
|
||||
}
|
||||
|
||||
Image *DocumentData::getReplyPreview(Data::FileOrigin origin) {
|
||||
if (!_thumbnail) {
|
||||
if (!hasThumbnail()) {
|
||||
return nullptr;
|
||||
} else if (!_replyPreview) {
|
||||
_replyPreview = std::make_unique<Data::ReplyPreview>(this);
|
||||
@ -1275,19 +1320,15 @@ QByteArray DocumentData::fileReference() const {
|
||||
|
||||
void DocumentData::refreshFileReference(const QByteArray &value) {
|
||||
_fileReference = value;
|
||||
_thumbnail->refreshFileReference(value);
|
||||
if (const auto data = sticker()) {
|
||||
data->loc.refreshFileReference(value);
|
||||
}
|
||||
_thumbnailLocation.refreshFileReference(value);
|
||||
}
|
||||
|
||||
void DocumentData::refreshStickerThumbFileReference() {
|
||||
if (const auto data = sticker()) {
|
||||
if (_thumbnail->loading()) {
|
||||
data->loc.refreshFileReference(
|
||||
_thumbnail->location().fileReference());
|
||||
}
|
||||
}
|
||||
// #TODO optimize
|
||||
//if (_thumbnailLoader) {
|
||||
// _thumbnailLocation.refreshFileReference(
|
||||
// _thumbnailLoader->fileReference());
|
||||
//}
|
||||
}
|
||||
|
||||
QString DocumentData::filename() const {
|
||||
@ -1462,11 +1503,6 @@ void DocumentData::recountIsImage() {
|
||||
}
|
||||
}
|
||||
|
||||
bool DocumentData::thumbnailEnoughForSticker() const {
|
||||
return !_thumbnail->isNull()
|
||||
&& ((_thumbnail->width() >= 128) || (_thumbnail->height() >= 128));
|
||||
}
|
||||
|
||||
void DocumentData::setRemoteLocation(
|
||||
int32 dc,
|
||||
uint64 access,
|
||||
|
@ -61,7 +61,6 @@ struct StickerData : public DocumentAdditionalData {
|
||||
bool animated = false;
|
||||
QString alt;
|
||||
MTPInputStickerSet set = MTP_inputStickerSetEmpty();
|
||||
StorageImageLocation loc; // doc thumb location
|
||||
};
|
||||
|
||||
struct SongData : public DocumentAdditionalData {
|
||||
@ -132,7 +131,6 @@ public:
|
||||
[[nodiscard]] Data::FileOrigin stickerSetOrigin() const;
|
||||
[[nodiscard]] Data::FileOrigin stickerOrGifOrigin() const;
|
||||
[[nodiscard]] bool isStickerSetInstalled() const;
|
||||
[[nodiscard]] bool thumbnailEnoughForSticker() const;
|
||||
[[nodiscard]] SongData *song();
|
||||
[[nodiscard]] const SongData *song() const;
|
||||
[[nodiscard]] VoiceData *voice();
|
||||
@ -158,11 +156,13 @@ public:
|
||||
[[nodiscard]] bool isPatternWallPaper() const;
|
||||
|
||||
[[nodiscard]] bool hasThumbnail() const;
|
||||
[[nodiscard]] bool thumbnailLoading() const;
|
||||
[[nodiscard]] bool thumbnailFailed() const;
|
||||
void loadThumbnail(Data::FileOrigin origin);
|
||||
[[nodiscard]] Image *thumbnail() const;
|
||||
void updateThumbnails(
|
||||
const QByteArray &inlineThumbnailBytes,
|
||||
ImagePtr thumbnail);
|
||||
const StorageImageLocation &thumbnail);
|
||||
const StorageImageLocation &thumbnailLocation() const;
|
||||
|
||||
[[nodiscard]] QByteArray inlineThumbnailBytes() const {
|
||||
return _inlineThumbnailBytes;
|
||||
@ -248,6 +248,7 @@ private:
|
||||
ImageType = 0x08,
|
||||
DownloadCancelled = 0x10,
|
||||
LoadedInMediaCache = 0x20,
|
||||
ThumbnailFailed = 0x40,
|
||||
};
|
||||
using Flags = base::flags<Flag>;
|
||||
friend constexpr bool is_flag_type(Flag) { return true; };
|
||||
@ -284,10 +285,12 @@ private:
|
||||
|
||||
void finishLoad();
|
||||
void handleLoaderUpdates();
|
||||
void destroyLoader() const;
|
||||
void destroyLoader();
|
||||
|
||||
bool saveFromDataChecked();
|
||||
|
||||
const not_null<Data::Session*> _owner;
|
||||
|
||||
// Two types of location: from MTProto by dc+access or from web by url
|
||||
int32 _dc = 0;
|
||||
uint64 _access = 0;
|
||||
@ -298,19 +301,19 @@ private:
|
||||
WebFileLocation _urlLocation;
|
||||
|
||||
QByteArray _inlineThumbnailBytes;
|
||||
ImagePtr _thumbnail;
|
||||
StorageImageLocation _thumbnailLocation;
|
||||
std::unique_ptr<FileLoader> _thumbnailLoader;
|
||||
int _thumbnailSize = 0;
|
||||
std::unique_ptr<Data::ReplyPreview> _replyPreview;
|
||||
std::weak_ptr<Data::DocumentMedia> _media;
|
||||
PhotoData *_goodThumbnailPhoto = nullptr;
|
||||
|
||||
not_null<Data::Session*> _owner;
|
||||
|
||||
FileLocation _location;
|
||||
std::unique_ptr<DocumentAdditionalData> _additional;
|
||||
int32 _duration = -1;
|
||||
mutable Flags _flags = kStreamingSupportedUnknown;
|
||||
GoodThumbnailState _goodThumbnailState = GoodThumbnailState();
|
||||
mutable std::unique_ptr<FileLoader> _loader;
|
||||
std::unique_ptr<FileLoader> _loader;
|
||||
|
||||
};
|
||||
|
||||
|
@ -130,6 +130,30 @@ Image *DocumentMedia::thumbnailInline() const {
|
||||
return _inlineThumbnail.get();
|
||||
}
|
||||
|
||||
Image *DocumentMedia::thumbnail() const {
|
||||
return _thumbnail.get();
|
||||
}
|
||||
|
||||
void DocumentMedia::thumbnailWanted(Data::FileOrigin origin) {
|
||||
if (!_thumbnail) {
|
||||
_owner->loadThumbnail(origin);
|
||||
}
|
||||
}
|
||||
|
||||
QSize DocumentMedia::thumbnailSize() const {
|
||||
if (const auto image = _thumbnail.get()) {
|
||||
return image->size();
|
||||
}
|
||||
const auto &location = _owner->thumbnailLocation();
|
||||
return { location.width(), location.height() };
|
||||
}
|
||||
|
||||
void DocumentMedia::setThumbnail(QImage thumbnail) {
|
||||
_thumbnail = std::make_unique<Image>(
|
||||
std::make_unique<Images::ImageSource>(std::move(thumbnail), "PNG"));
|
||||
_owner->session().downloaderTaskFinished().notify();
|
||||
}
|
||||
|
||||
void DocumentMedia::checkStickerLarge() {
|
||||
if (_sticker) {
|
||||
return;
|
||||
@ -224,9 +248,19 @@ bool DocumentMedia::canBePlayed() const {
|
||||
&& (loaded() || _owner->canBeStreamed());
|
||||
}
|
||||
|
||||
bool DocumentMedia::thumbnailEnoughForSticker() const {
|
||||
const auto &location = owner()->thumbnailLocation();
|
||||
const auto size = _thumbnail
|
||||
? QSize(_thumbnail->width(), _thumbnail->height())
|
||||
: location.valid()
|
||||
? QSize(location.width(), location.height())
|
||||
: QSize();
|
||||
return (size.width() >= 128) || (size.height() >= 128);
|
||||
}
|
||||
|
||||
void DocumentMedia::checkStickerSmall() {
|
||||
const auto data = _owner->sticker();
|
||||
if ((data && data->animated) || _owner->thumbnailEnoughForSticker()) {
|
||||
if ((data && data->animated) || thumbnailEnoughForSticker()) {
|
||||
_owner->loadThumbnail(_owner->stickerSetOrigin());
|
||||
if (data && data->animated) {
|
||||
automaticLoad(_owner->stickerSetOrigin(), nullptr);
|
||||
@ -243,8 +277,8 @@ Image *DocumentMedia::getStickerLarge() {
|
||||
|
||||
Image *DocumentMedia::getStickerSmall() {
|
||||
const auto data = _owner->sticker();
|
||||
if ((data && data->animated) || _owner->thumbnailEnoughForSticker()) {
|
||||
return _owner->thumbnail();
|
||||
if ((data && data->animated) || thumbnailEnoughForSticker()) {
|
||||
return thumbnail();
|
||||
}
|
||||
return _sticker.get();
|
||||
}
|
||||
|
@ -21,10 +21,14 @@ public:
|
||||
[[nodiscard]] not_null<DocumentData*> owner() const;
|
||||
|
||||
void goodThumbnailWanted();
|
||||
[[nodiscard]] Image *goodThumbnail() const;
|
||||
[[nodiscard]] Image *goodThumbnail() const; // #TODO optimize QImage-wrap
|
||||
void setGoodThumbnail(QImage thumbnail);
|
||||
|
||||
[[nodiscard]] Image *thumbnailInline() const;
|
||||
[[nodiscard]] Image *thumbnail() const;
|
||||
[[nodiscard]] QSize thumbnailSize() const;
|
||||
void thumbnailWanted(Data::FileOrigin origin);
|
||||
void setThumbnail(QImage thumbnail);
|
||||
|
||||
void checkStickerLarge();
|
||||
void checkStickerSmall();
|
||||
@ -55,9 +59,12 @@ private:
|
||||
not_null<DocumentData*> document,
|
||||
QByteArray data);
|
||||
|
||||
[[nodiscard]] bool thumbnailEnoughForSticker() const;
|
||||
|
||||
const not_null<DocumentData*> _owner;
|
||||
std::unique_ptr<Image> _goodThumbnail;
|
||||
mutable std::unique_ptr<Image> _inlineThumbnail;
|
||||
std::unique_ptr<Image> _thumbnail;
|
||||
std::unique_ptr<Image> _sticker;
|
||||
QByteArray _bytes;
|
||||
Flags _flags;
|
||||
|
@ -60,16 +60,15 @@ void ReplyPreview::prepare(not_null<Image*> image, Images::Options options) {
|
||||
|
||||
Image *ReplyPreview::image(Data::FileOrigin origin) {
|
||||
if (_document) {
|
||||
const auto thumbnail = _document->thumbnail();
|
||||
Assert(thumbnail != nullptr);
|
||||
if (!_image || (!_good && thumbnail->loaded())) {
|
||||
const auto thumbnail = _documentMedia->thumbnail();
|
||||
if (!_image || (!_good && thumbnail)) {
|
||||
const auto option = _document->isVideoMessage()
|
||||
? Images::Option::Circled
|
||||
: Images::Option::None;
|
||||
if (thumbnail->loaded()) {
|
||||
if (thumbnail) {
|
||||
prepare(thumbnail, option);
|
||||
} else {
|
||||
thumbnail->load(origin);
|
||||
_documentMedia->thumbnailWanted(origin);
|
||||
if (const auto image = _documentMedia->thumbnailInline()) {
|
||||
prepare(image, option | Images::Option::Blurred);
|
||||
}
|
||||
|
@ -2381,9 +2381,11 @@ not_null<DocumentData*> Session::processDocument(
|
||||
case mtpc_document: {
|
||||
const auto &fields = data.c_document();
|
||||
const auto mime = qs(fields.vmime_type());
|
||||
// #TODO optimize
|
||||
const auto format = Core::IsMimeSticker(mime)
|
||||
? "WEBP"
|
||||
: "JPG";
|
||||
Images::Create(std::move(thumb), format);
|
||||
return document(
|
||||
fields.vid().v,
|
||||
fields.vaccess_hash().v,
|
||||
@ -2392,10 +2394,9 @@ not_null<DocumentData*> Session::processDocument(
|
||||
fields.vattributes().v,
|
||||
mime,
|
||||
QByteArray(),
|
||||
Images::Create(std::move(thumb), format),
|
||||
StorageImageLocation(),
|
||||
fields.vdc_id().v,
|
||||
fields.vsize().v,
|
||||
StorageImageLocation());
|
||||
fields.vsize().v);
|
||||
} break;
|
||||
}
|
||||
Unexpected("Type in Session::document() with thumb.");
|
||||
@ -2409,10 +2410,9 @@ not_null<DocumentData*> Session::document(
|
||||
const QVector<MTPDocumentAttribute> &attributes,
|
||||
const QString &mime,
|
||||
const QByteArray &inlineThumbnailBytes,
|
||||
const ImagePtr &thumbnail,
|
||||
const StorageImageLocation &thumbnailLocation,
|
||||
int32 dc,
|
||||
int32 size,
|
||||
const StorageImageLocation &thumbLocation) {
|
||||
int32 size) {
|
||||
const auto result = document(id);
|
||||
documentApplyFields(
|
||||
result,
|
||||
@ -2422,10 +2422,9 @@ not_null<DocumentData*> Session::document(
|
||||
attributes,
|
||||
mime,
|
||||
inlineThumbnailBytes,
|
||||
thumbnail,
|
||||
thumbnailLocation,
|
||||
dc,
|
||||
size,
|
||||
thumbLocation);
|
||||
size);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2489,6 +2488,7 @@ DocumentData *Session::documentFromWeb(
|
||||
DocumentData *Session::documentFromWeb(
|
||||
const MTPDwebDocument &data,
|
||||
ImagePtr thumb) {
|
||||
// #TODO optimize thumb
|
||||
const auto result = document(
|
||||
rand_value<DocumentId>(),
|
||||
uint64(0),
|
||||
@ -2497,10 +2497,9 @@ DocumentData *Session::documentFromWeb(
|
||||
data.vattributes().v,
|
||||
data.vmime_type().v,
|
||||
QByteArray(),
|
||||
thumb,
|
||||
StorageImageLocation(),
|
||||
MTP::maindc(),
|
||||
int32(0), // data.vsize().v
|
||||
StorageImageLocation());
|
||||
int32(0)); // data.vsize().v
|
||||
result->setWebLocation(WebFileLocation(
|
||||
data.vurl().v,
|
||||
data.vaccess_hash().v));
|
||||
@ -2510,6 +2509,7 @@ DocumentData *Session::documentFromWeb(
|
||||
DocumentData *Session::documentFromWeb(
|
||||
const MTPDwebDocumentNoProxy &data,
|
||||
ImagePtr thumb) {
|
||||
// #TODO optimize thumb
|
||||
const auto result = document(
|
||||
rand_value<DocumentId>(),
|
||||
uint64(0),
|
||||
@ -2518,10 +2518,9 @@ DocumentData *Session::documentFromWeb(
|
||||
data.vattributes().v,
|
||||
data.vmime_type().v,
|
||||
QByteArray(),
|
||||
thumb,
|
||||
StorageImageLocation(),
|
||||
MTP::maindc(),
|
||||
int32(0), // data.vsize().v
|
||||
StorageImageLocation());
|
||||
int32(0)); // data.vsize().v
|
||||
result->setContentUrl(qs(data.vurl()));
|
||||
return result;
|
||||
}
|
||||
@ -2539,7 +2538,8 @@ void Session::documentApplyFields(
|
||||
const MTPDdocument &data) {
|
||||
const auto inlineThumbnailBytes = FindDocumentInlineThumbnail(data);
|
||||
const auto thumbnailSize = FindDocumentThumbnail(data);
|
||||
const auto thumbnail = Images::Create(data, thumbnailSize);
|
||||
// #TODO optimize
|
||||
const auto thumbnail = Images::Create(data, thumbnailSize)->location();
|
||||
documentApplyFields(
|
||||
document,
|
||||
data.vaccess_hash().v,
|
||||
@ -2550,8 +2550,7 @@ void Session::documentApplyFields(
|
||||
inlineThumbnailBytes,
|
||||
thumbnail,
|
||||
data.vdc_id().v,
|
||||
data.vsize().v,
|
||||
thumbnail->location());
|
||||
data.vsize().v);
|
||||
}
|
||||
|
||||
void Session::documentApplyFields(
|
||||
@ -2562,16 +2561,15 @@ void Session::documentApplyFields(
|
||||
const QVector<MTPDocumentAttribute> &attributes,
|
||||
const QString &mime,
|
||||
const QByteArray &inlineThumbnailBytes,
|
||||
const ImagePtr &thumbnail,
|
||||
const StorageImageLocation &thumbnailLocation,
|
||||
int32 dc,
|
||||
int32 size,
|
||||
const StorageImageLocation &thumbLocation) {
|
||||
int32 size) {
|
||||
if (!date) {
|
||||
return;
|
||||
}
|
||||
document->date = date;
|
||||
document->setMimeString(mime);
|
||||
document->updateThumbnails(inlineThumbnailBytes, thumbnail);
|
||||
document->updateThumbnails(inlineThumbnailBytes, thumbnailLocation);
|
||||
document->size = size;
|
||||
document->setattributes(attributes);
|
||||
|
||||
@ -2580,12 +2578,6 @@ void Session::documentApplyFields(
|
||||
if (dc != 0 && access != 0) {
|
||||
document->setRemoteLocation(dc, access, fileReference);
|
||||
}
|
||||
|
||||
if (document->sticker()
|
||||
&& !document->sticker()->loc.valid()
|
||||
&& thumbLocation.valid()) {
|
||||
document->sticker()->loc = thumbLocation;
|
||||
}
|
||||
}
|
||||
|
||||
not_null<WebPageData*> Session::webpage(WebPageId id) {
|
||||
|
@ -499,10 +499,9 @@ public:
|
||||
const QVector<MTPDocumentAttribute> &attributes,
|
||||
const QString &mime,
|
||||
const QByteArray &inlineThumbnailBytes,
|
||||
const ImagePtr &thumbnail,
|
||||
const StorageImageLocation &thumbnailLocation,
|
||||
int32 dc,
|
||||
int32 size,
|
||||
const StorageImageLocation &thumbLocation);
|
||||
int32 size);
|
||||
void documentConvert(
|
||||
not_null<DocumentData*> original,
|
||||
const MTPDocument &data);
|
||||
@ -754,10 +753,9 @@ private:
|
||||
const QVector<MTPDocumentAttribute> &attributes,
|
||||
const QString &mime,
|
||||
const QByteArray &inlineThumbnailBytes,
|
||||
const ImagePtr &thumbnail,
|
||||
const StorageImageLocation &thumbnailLocation,
|
||||
int32 dc,
|
||||
int32 size,
|
||||
const StorageImageLocation &thumbLocation);
|
||||
int32 size);
|
||||
DocumentData *documentFromWeb(
|
||||
const MTPDwebDocument &data,
|
||||
ImagePtr thumb);
|
||||
|
@ -118,12 +118,8 @@ DocumentData *WallPaper::document() const {
|
||||
return _document;
|
||||
}
|
||||
|
||||
Image *WallPaper::thumbnail() const {
|
||||
return _thumbnail
|
||||
? _thumbnail.get()
|
||||
: _document
|
||||
? _document->thumbnail()
|
||||
: nullptr;
|
||||
Image *WallPaper::localThumbnail() const {
|
||||
return _thumbnail.get();
|
||||
}
|
||||
|
||||
bool WallPaper::isPattern() const {
|
||||
@ -143,7 +139,7 @@ bool WallPaper::isDark() const {
|
||||
}
|
||||
|
||||
bool WallPaper::isLocal() const {
|
||||
return !document() && thumbnail();
|
||||
return !document() && _thumbnail;
|
||||
}
|
||||
|
||||
bool WallPaper::isBlurred() const {
|
||||
@ -187,10 +183,13 @@ QString WallPaper::shareUrl() const {
|
||||
: base + '?' + params.join('&');
|
||||
}
|
||||
|
||||
void WallPaper::loadThumbnail() const {
|
||||
void WallPaper::loadLocalThumbnail() const {
|
||||
if (_thumbnail) {
|
||||
_thumbnail->load(fileOrigin());
|
||||
}
|
||||
}
|
||||
|
||||
void WallPaper::loadDocumentThumbnail() const {
|
||||
if (_document) {
|
||||
_document->loadThumbnail(fileOrigin());
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
[[nodiscard]] WallPaperId id() const;
|
||||
[[nodiscard]] std::optional<QColor> backgroundColor() const;
|
||||
[[nodiscard]] DocumentData *document() const;
|
||||
[[nodiscard]] Image *thumbnail() const;
|
||||
[[nodiscard]] Image *localThumbnail() const; // #TODO optimize QImage-wrap
|
||||
[[nodiscard]] bool isPattern() const;
|
||||
[[nodiscard]] bool isDefault() const;
|
||||
[[nodiscard]] bool isCreator() const;
|
||||
@ -34,7 +34,8 @@ public:
|
||||
[[nodiscard]] QString shareUrl() const;
|
||||
|
||||
void loadDocument() const;
|
||||
void loadThumbnail() const;
|
||||
void loadLocalThumbnail() const;
|
||||
void loadDocumentThumbnail() const;
|
||||
[[nodiscard]] FileOrigin fileOrigin() const;
|
||||
|
||||
[[nodiscard]] MTPInputWallPaper mtpInput() const;
|
||||
|
@ -613,6 +613,7 @@ void Element::checkHeavyPart() {
|
||||
}
|
||||
|
||||
void Element::unloadHeavyPart() {
|
||||
history()->owner().unregisterHeavyViewPart(this);
|
||||
if (_media) {
|
||||
_media->unloadHeavyPart();
|
||||
}
|
||||
|
@ -104,11 +104,10 @@ void Document::createComponents(bool caption) {
|
||||
mask |= HistoryDocumentVoice::Bit();
|
||||
} else {
|
||||
mask |= HistoryDocumentNamed::Bit();
|
||||
if (const auto thumb = _data->thumbnail()) {
|
||||
if (_data->hasThumbnail()) {
|
||||
if (!_data->isSong()
|
||||
&& thumb->width()
|
||||
&& thumb->height()
|
||||
&& !Data::IsExecutableName(_data->filename())) {
|
||||
_data->loadThumbnail(_realParent->fullId());
|
||||
mask |= HistoryDocumentThumbed::Bit();
|
||||
}
|
||||
}
|
||||
@ -157,9 +156,9 @@ QSize Document::countOptimalSize() {
|
||||
}
|
||||
auto thumbed = Get<HistoryDocumentThumbed>();
|
||||
if (thumbed) {
|
||||
_data->loadThumbnail(_realParent->fullId());
|
||||
auto tw = style::ConvertScale(_data->thumbnail()->width());
|
||||
auto th = style::ConvertScale(_data->thumbnail()->height());
|
||||
const auto &location = _data->thumbnailLocation();
|
||||
auto tw = style::ConvertScale(location.width());
|
||||
auto th = style::ConvertScale(location.height());
|
||||
if (tw > th) {
|
||||
thumbed->_thumbw = (tw * st::msgFileThumbSize) / th;
|
||||
} else {
|
||||
@ -278,15 +277,10 @@ void Document::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
|
||||
auto roundRadius = inWebPage ? ImageRoundRadius::Small : ImageRoundRadius::Large;
|
||||
QRect rthumb(style::rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width()));
|
||||
QPixmap thumb;
|
||||
if (const auto normal = _data->thumbnail()) {
|
||||
if (normal->loaded()) {
|
||||
thumb = normal->pixSingle(_realParent->fullId(), thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius);
|
||||
} else {
|
||||
_data->loadThumbnail(_realParent->fullId());
|
||||
if (const auto blurred = _dataMedia->thumbnailInline()) {
|
||||
thumb = blurred->pixBlurredSingle(_realParent->fullId(), thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius);
|
||||
}
|
||||
}
|
||||
if (const auto normal = _dataMedia->thumbnail()) {
|
||||
thumb = normal->pixSingle(_realParent->fullId(), thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius);
|
||||
} else if (const auto blurred = _dataMedia->thumbnailInline()) {
|
||||
thumb = blurred->pixBlurredSingle(_realParent->fullId(), thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius);
|
||||
}
|
||||
p.drawPixmap(rthumb.topLeft(), thumb);
|
||||
if (selected) {
|
||||
@ -515,6 +509,9 @@ void Document::ensureDataMediaCreated() const {
|
||||
return;
|
||||
}
|
||||
_dataMedia = _data->createMediaView();
|
||||
if (Get<HistoryDocumentThumbed>()) {
|
||||
_dataMedia->thumbnailWanted(_realParent->fullId());
|
||||
}
|
||||
history()->owner().registerHeavyViewPart(_parent);
|
||||
}
|
||||
|
||||
|
@ -103,10 +103,9 @@ QSize Gif::sizeForAspectRatio() const {
|
||||
//if (!_data->dimensions.isEmpty()) {
|
||||
// return _data->dimensions;
|
||||
//}
|
||||
if (const auto thumb = _data->thumbnail()) {
|
||||
if (!thumb->size().isEmpty()) {
|
||||
return thumb->size();
|
||||
}
|
||||
if (_data->hasThumbnail()) {
|
||||
const auto &location = _data->thumbnailLocation();
|
||||
return { location.width(), location.height() };
|
||||
}
|
||||
return { 1, 1 };
|
||||
}
|
||||
@ -240,8 +239,9 @@ QSize Gif::videoSize() const {
|
||||
return streamed->player().videoSize();
|
||||
} else if (!_data->dimensions.isEmpty()) {
|
||||
return _data->dimensions;
|
||||
} else if (const auto thumbnail = _data->thumbnail()) {
|
||||
return thumbnail->size();
|
||||
} else if (_data->hasThumbnail()) {
|
||||
const auto &location = _data->thumbnailLocation();
|
||||
return QSize(location.width(), location.height());
|
||||
} else {
|
||||
return QSize(1, 1);
|
||||
}
|
||||
@ -417,8 +417,8 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
|
||||
if (good) {
|
||||
good->load({});
|
||||
}
|
||||
const auto normal = _data->thumbnail();
|
||||
if (normal && normal->loaded()) {
|
||||
const auto normal = _dataMedia->thumbnail();
|
||||
if (normal) {
|
||||
if (normal->width() >= kUseNonBlurredThreshold
|
||||
|| normal->height() >= kUseNonBlurredThreshold) {
|
||||
p.drawPixmap(rthumb.topLeft(), normal->pixSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
|
||||
@ -1087,6 +1087,7 @@ void Gif::ensureDataMediaCreated() const {
|
||||
}
|
||||
_dataMedia = _data->createMediaView();
|
||||
_dataMedia->goodThumbnailWanted();
|
||||
_dataMedia->thumbnailWanted(_realParent->fullId());
|
||||
history()->owner().registerHeavyViewPart(_parent);
|
||||
}
|
||||
|
||||
@ -1140,8 +1141,8 @@ void Gif::validateGroupedCache(
|
||||
|
||||
const auto good = _dataMedia->goodThumbnail();
|
||||
const auto useGood = (good && good->loaded());
|
||||
const auto thumb = _data->thumbnail();
|
||||
const auto useThumb = (thumb && thumb->loaded());
|
||||
const auto thumb = _dataMedia->thumbnail();
|
||||
const auto useThumb = (thumb != nullptr);
|
||||
const auto image = useGood
|
||||
? good
|
||||
: useThumb
|
||||
@ -1153,9 +1154,6 @@ void Gif::validateGroupedCache(
|
||||
&& thumb->height() < kUseNonBlurredThreshold));
|
||||
if (good && !useGood) {
|
||||
good->load({});
|
||||
if (!useThumb) {
|
||||
_data->loadThumbnail(_realParent->fullId());
|
||||
}
|
||||
}
|
||||
|
||||
const auto loadLevel = useGood ? 3 : useThumb ? 2 : image ? 1 : 0;
|
||||
|
@ -225,7 +225,7 @@ QPixmap Sticker::paintedPixmap(bool selected) const {
|
||||
return selected
|
||||
? good->pixColored(o, c, w, h)
|
||||
: good->pix(o, w, h);
|
||||
} else if (const auto thumbnail = _data->thumbnail()) {
|
||||
} else if (const auto thumbnail = _dataMedia->thumbnail()) {
|
||||
return selected
|
||||
? thumbnail->pixBlurredColored(o, c, w, h)
|
||||
: thumbnail->pixBlurred(o, w, h);
|
||||
@ -262,6 +262,7 @@ void Sticker::ensureDataMediaCreated() const {
|
||||
}
|
||||
_dataMedia = _data->createMediaView();
|
||||
_dataMedia->goodThumbnailWanted();
|
||||
_dataMedia->thumbnailWanted(_parent->data()->fullId());
|
||||
_parent->history()->owner().registerHeavyViewPart(_parent);
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,9 @@ QSize ThemeDocument::countOptimalSize() {
|
||||
if (_data->isTheme()) {
|
||||
return st::historyThemeSize;
|
||||
}
|
||||
auto tw = style::ConvertScale(_data->thumbnail()->width());
|
||||
auto th = style::ConvertScale(_data->thumbnail()->height());
|
||||
const auto &location = _data->thumbnailLocation();
|
||||
auto tw = style::ConvertScale(location.width());
|
||||
auto th = style::ConvertScale(location.height());
|
||||
if (!tw || !th) {
|
||||
tw = th = 1;
|
||||
}
|
||||
@ -86,8 +87,9 @@ QSize ThemeDocument::countCurrentSize(int newWidth) {
|
||||
_pixh = st::historyThemeSize.height();
|
||||
return st::historyThemeSize;
|
||||
}
|
||||
auto tw = style::ConvertScale(_data->thumbnail()->width());
|
||||
auto th = style::ConvertScale(_data->thumbnail()->height());
|
||||
const auto &location = _data->thumbnailLocation();
|
||||
auto tw = style::ConvertScale(location.width());
|
||||
auto th = style::ConvertScale(location.height());
|
||||
if (!tw || !th) {
|
||||
tw = th = 1;
|
||||
}
|
||||
@ -193,6 +195,7 @@ void ThemeDocument::ensureDataMediaCreated() const {
|
||||
}
|
||||
_dataMedia = _data->createMediaView();
|
||||
_dataMedia->goodThumbnailWanted();
|
||||
_dataMedia->thumbnailWanted(_realParent->fullId());
|
||||
_parent->history()->owner().registerHeavyViewPart(_parent);
|
||||
}
|
||||
|
||||
@ -209,11 +212,11 @@ void ThemeDocument::validateThumbnail() const {
|
||||
good->load({});
|
||||
}
|
||||
}
|
||||
if (_thumbnailGood >= 0 || !_data->thumbnail()) {
|
||||
if (_thumbnailGood >= 0 || !_dataMedia->thumbnail()) {
|
||||
return;
|
||||
}
|
||||
if (_data->thumbnail()->loaded()) {
|
||||
prepareThumbnailFrom(_data->thumbnail(), 0);
|
||||
if (const auto normal = _dataMedia->thumbnail()) {
|
||||
prepareThumbnailFrom(normal, 0);
|
||||
} else if (_thumbnail.isNull()) {
|
||||
if (const auto blurred = _dataMedia->thumbnailInline()) {
|
||||
prepareThumbnailFrom(blurred, -1);
|
||||
@ -234,8 +237,9 @@ void ThemeDocument::prepareThumbnailFrom(
|
||||
? Images::Option::TransparentBackground
|
||||
: Images::Option(0));
|
||||
auto original = image->original();
|
||||
auto tw = isTheme ? _pixw : style::ConvertScale(_data->thumbnail()->width());
|
||||
auto th = isTheme ? _pixh : style::ConvertScale(_data->thumbnail()->height());
|
||||
const auto &location = _data->thumbnailLocation();
|
||||
auto tw = isTheme ? _pixw : style::ConvertScale(location.width());
|
||||
auto th = isTheme ? _pixh : style::ConvertScale(location.height());
|
||||
if (!tw || !th) {
|
||||
tw = th = 1;
|
||||
}
|
||||
|
@ -63,9 +63,7 @@ int FileBase::content_width() const {
|
||||
if (document->dimensions.width() > 0) {
|
||||
return document->dimensions.width();
|
||||
}
|
||||
if (const auto thumb = document->thumbnail()) {
|
||||
return style::ConvertScale(thumb->width());
|
||||
}
|
||||
return style::ConvertScale(document->thumbnailLocation().width());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -75,9 +73,7 @@ int FileBase::content_height() const {
|
||||
if (document->dimensions.height() > 0) {
|
||||
return document->dimensions.height();
|
||||
}
|
||||
if (const auto thumb = document->thumbnail()) {
|
||||
return style::ConvertScale(thumb->height());
|
||||
}
|
||||
return style::ConvertScale(document->thumbnailLocation().height());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -91,15 +87,6 @@ int FileBase::content_duration() const {
|
||||
return getResultDuration();
|
||||
}
|
||||
|
||||
Image *FileBase::content_thumb() const {
|
||||
if (const auto document = getShownDocument()) {
|
||||
if (const auto thumb = document->thumbnail()) {
|
||||
return thumb;
|
||||
}
|
||||
}
|
||||
return getResultThumb();
|
||||
}
|
||||
|
||||
Gif::Gif(not_null<Context*> context, Result *result) : FileBase(context, result) {
|
||||
}
|
||||
|
||||
@ -329,7 +316,7 @@ void Gif::validateThumbnail(
|
||||
void Gif::prepareThumbnail(QSize size, QSize frame) const {
|
||||
if (const auto document = getShownDocument()) {
|
||||
ensureDataMediaCreated(document);
|
||||
validateThumbnail(document->thumbnail(), size, frame, true);
|
||||
validateThumbnail(_dataMedia->thumbnail(), size, frame, true);
|
||||
validateThumbnail(_dataMedia->thumbnailInline(), size, frame, false);
|
||||
} else {
|
||||
validateThumbnail(getResultThumb(), size, frame, true);
|
||||
@ -341,6 +328,7 @@ void Gif::ensureDataMediaCreated(not_null<DocumentData*> document) const {
|
||||
return;
|
||||
}
|
||||
_dataMedia = document->createMediaView();
|
||||
_dataMedia->thumbnailWanted(fileOrigin());
|
||||
}
|
||||
|
||||
void Gif::ensureAnimation() const {
|
||||
@ -679,7 +667,8 @@ void Photo::prepareThumbnail(QSize size, QSize frame) const {
|
||||
}
|
||||
}
|
||||
|
||||
Video::Video(not_null<Context*> context, Result *result) : FileBase(context, result)
|
||||
Video::Video(not_null<Context*> context, Result *result)
|
||||
: FileBase(context, result)
|
||||
, _link(getResultPreviewHandler())
|
||||
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
|
||||
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
|
||||
@ -689,8 +678,17 @@ Video::Video(not_null<Context*> context, Result *result) : FileBase(context, res
|
||||
}
|
||||
}
|
||||
|
||||
bool Video::withThumbnail() const {
|
||||
if (const auto document = getShownDocument()) {
|
||||
if (document->hasThumbnail()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return getResultThumb() != nullptr;
|
||||
}
|
||||
|
||||
void Video::initDimensions() {
|
||||
const auto withThumb = (content_thumb() != nullptr);
|
||||
const auto withThumb = withThumbnail();
|
||||
|
||||
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
|
||||
int32 textWidth = _maxw - (withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0);
|
||||
@ -719,7 +717,7 @@ void Video::initDimensions() {
|
||||
void Video::paint(Painter &p, const QRect &clip, const PaintContext *context) const {
|
||||
int left = st::inlineThumbSize + st::inlineThumbSkip;
|
||||
|
||||
const auto withThumb = (content_thumb() != nullptr);
|
||||
const auto withThumb = withThumbnail();
|
||||
if (withThumb) {
|
||||
prepareThumbnail({ st::inlineThumbSize, st::inlineThumbSize });
|
||||
if (_thumb.isNull()) {
|
||||
@ -767,9 +765,22 @@ TextState Video::getState(
|
||||
}
|
||||
|
||||
void Video::prepareThumbnail(QSize size) const {
|
||||
Expects(content_thumb() != nullptr);
|
||||
|
||||
const auto thumb = content_thumb();
|
||||
const auto document = getShownDocument();
|
||||
if (document->hasThumbnail()) {
|
||||
if (!_documentMedia) {
|
||||
_documentMedia = document->createMediaView();
|
||||
_documentMedia->thumbnailWanted(fileOrigin());
|
||||
}
|
||||
if (!_documentMedia->thumbnail()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const auto thumb = document->hasThumbnail()
|
||||
? _documentMedia->thumbnail()
|
||||
: getResultThumb();
|
||||
if (!thumb) {
|
||||
return;
|
||||
}
|
||||
const auto origin = fileOrigin();
|
||||
if (thumb->loaded()) {
|
||||
if (_thumb.size() != size * cIntRetinaFactor()) {
|
||||
@ -1424,7 +1435,7 @@ void Game::prepareThumbnail(QSize size) const {
|
||||
validateThumbnail(photo->thumbnailInline(), size, false);
|
||||
} else if (const auto document = getResultDocument()) {
|
||||
Assert(_dataMedia != nullptr);
|
||||
validateThumbnail(document->thumbnail(), size, true);
|
||||
validateThumbnail(_dataMedia->thumbnail(), size, true);
|
||||
validateThumbnail(_dataMedia->thumbnailInline(), size, false);
|
||||
}
|
||||
}
|
||||
@ -1434,6 +1445,7 @@ void Game::ensureDataMediaCreated(not_null<DocumentData*> document) const {
|
||||
return;
|
||||
}
|
||||
_dataMedia = document->createMediaView();
|
||||
_dataMedia->thumbnailWanted(fileOrigin());
|
||||
}
|
||||
|
||||
void Game::validateThumbnail(Image *image, QSize size, bool good) const {
|
||||
|
@ -38,7 +38,7 @@ protected:
|
||||
int content_width() const;
|
||||
int content_height() const;
|
||||
int content_duration() const;
|
||||
Image *content_thumb() const;
|
||||
|
||||
};
|
||||
|
||||
class DeleteSavedGifClickHandler : public LeftButtonClickHandler {
|
||||
@ -224,10 +224,12 @@ private:
|
||||
ClickHandlerPtr _link;
|
||||
|
||||
mutable QPixmap _thumb;
|
||||
mutable std::shared_ptr<Data::DocumentMedia> _documentMedia;
|
||||
Ui::Text::String _title, _description;
|
||||
QString _duration;
|
||||
int _durationWidth = 0;
|
||||
|
||||
[[nodiscard]] bool withThumbnail() const;
|
||||
void prepareThumbnail(QSize size) const;
|
||||
|
||||
};
|
||||
|
@ -1330,6 +1330,8 @@ void MainWidget::setChatBackground(
|
||||
_background = std::make_unique<SettingBackground>(background);
|
||||
if (const auto document = _background->data.document()) {
|
||||
_background->dataMedia = document->createMediaView();
|
||||
_background->dataMedia->thumbnailWanted(
|
||||
_background->data.fileOrigin());
|
||||
}
|
||||
_background->data.loadDocument();
|
||||
checkChatBackground();
|
||||
@ -1352,9 +1354,9 @@ void MainWidget::setReadyChatBackground(
|
||||
|
||||
if (image.isNull()
|
||||
&& !background.document()
|
||||
&& background.thumbnail()
|
||||
&& background.thumbnail()->loaded()) {
|
||||
image = background.thumbnail()->original();
|
||||
&& background.localThumbnail()
|
||||
&& background.localThumbnail()->loaded()) {
|
||||
image = background.localThumbnail()->original();
|
||||
}
|
||||
|
||||
const auto resetToDefault = image.isNull()
|
||||
@ -1381,7 +1383,7 @@ float64 MainWidget::chatBackgroundProgress() const {
|
||||
return 1.;
|
||||
} else if (const auto document = _background->data.document()) {
|
||||
return _background->dataMedia->progress();
|
||||
} else if (const auto thumbnail = _background->data.thumbnail()) {
|
||||
} else if (const auto thumbnail = _background->data.localThumbnail()) {
|
||||
return thumbnail->progress();
|
||||
}
|
||||
}
|
||||
@ -1415,7 +1417,13 @@ void MainWidget::checkChatBackground() {
|
||||
}
|
||||
|
||||
Image *MainWidget::newBackgroundThumb() {
|
||||
return _background ? _background->data.thumbnail() : nullptr;
|
||||
return !_background
|
||||
? nullptr
|
||||
: _background->data.localThumbnail()
|
||||
? _background->data.localThumbnail()
|
||||
: _background->dataMedia
|
||||
? _background->dataMedia->thumbnail()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void MainWidget::messageDataReceived(ChannelData *channel, MsgId msgId) {
|
||||
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_user_photos.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_document_media.h"
|
||||
#include "data/data_media_types.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_web_page.h"
|
||||
@ -133,6 +134,11 @@ public:
|
||||
Image *image,
|
||||
Data::FileOrigin origin,
|
||||
Fn<void()> handler);
|
||||
Thumb(
|
||||
Key key,
|
||||
not_null<DocumentData*> document,
|
||||
Data::FileOrigin origin,
|
||||
Fn<void()> handler);
|
||||
|
||||
int leftToUpdate() const;
|
||||
int rightToUpdate() const;
|
||||
@ -158,6 +164,7 @@ private:
|
||||
|
||||
ClickHandlerPtr _link;
|
||||
const Key _key;
|
||||
std::shared_ptr<Data::DocumentMedia> _documentMedia;
|
||||
Image *_image = nullptr;
|
||||
Data::FileOrigin _origin;
|
||||
State _state = State::Alive;
|
||||
@ -186,6 +193,22 @@ GroupThumbs::Thumb::Thumb(
|
||||
validateImage();
|
||||
}
|
||||
|
||||
GroupThumbs::Thumb::Thumb(
|
||||
Key key,
|
||||
not_null<DocumentData*> document,
|
||||
Data::FileOrigin origin,
|
||||
Fn<void()> handler)
|
||||
: _key(key)
|
||||
, _documentMedia(document->createMediaView())
|
||||
, _origin(origin) {
|
||||
_link = std::make_shared<LambdaClickHandler>(std::move(handler));
|
||||
_fullWidth = std::min(
|
||||
wantedPixSize().width(),
|
||||
st::mediaviewGroupWidthMax);
|
||||
_documentMedia->thumbnailWanted(origin);
|
||||
validateImage();
|
||||
}
|
||||
|
||||
QSize GroupThumbs::Thumb::wantedPixSize() const {
|
||||
const auto originalWidth = _image ? std::max(_image->width(), 1) : 1;
|
||||
const auto originalHeight = _image ? std::max(_image->height(), 1) : 1;
|
||||
@ -195,6 +218,9 @@ QSize GroupThumbs::Thumb::wantedPixSize() const {
|
||||
}
|
||||
|
||||
void GroupThumbs::Thumb::validateImage() {
|
||||
if (!_image && _documentMedia) {
|
||||
_image = _documentMedia->thumbnail();
|
||||
}
|
||||
if (!_full.isNull() || !_image) {
|
||||
return;
|
||||
}
|
||||
@ -524,7 +550,7 @@ auto GroupThumbs::createThumb(Key key)
|
||||
if (const auto photo = media->photo()) {
|
||||
return createThumb(key, photo->thumbnail());
|
||||
} else if (const auto document = media->document()) {
|
||||
return createThumb(key, document->thumbnail());
|
||||
return createThumb(key, document);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -559,7 +585,7 @@ auto GroupThumbs::createThumb(
|
||||
if (const auto photo = base::get_if<PhotoData*>(&item)) {
|
||||
return createThumb(key, (*photo)->thumbnail());
|
||||
} else if (const auto document = base::get_if<DocumentData*>(&item)) {
|
||||
return createThumb(key, (*document)->thumbnail());
|
||||
return createThumb(key, (*document));
|
||||
}
|
||||
return createThumb(key, nullptr);
|
||||
}
|
||||
@ -575,6 +601,17 @@ auto GroupThumbs::createThumb(Key key, Image *image)
|
||||
});
|
||||
}
|
||||
|
||||
auto GroupThumbs::createThumb(Key key, not_null<DocumentData*> document)
|
||||
-> std::unique_ptr<Thumb> {
|
||||
const auto weak = base::make_weak(this);
|
||||
const auto origin = ComputeFileOrigin(key, _context);
|
||||
return std::make_unique<Thumb>(key, document, origin, [=] {
|
||||
if (const auto strong = weak.get()) {
|
||||
strong->_activateStream.fire_copy(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
auto GroupThumbs::validateCacheEntry(Key key) -> not_null<Thumb*> {
|
||||
const auto i = _cache.find(key);
|
||||
return (i != _cache.end())
|
||||
|
@ -101,6 +101,9 @@ private:
|
||||
const WebPageCollage &collage,
|
||||
int index);
|
||||
std::unique_ptr<Thumb> createThumb(Key key, Image *image);
|
||||
std::unique_ptr<Thumb> createThumb(
|
||||
Key key,
|
||||
not_null<DocumentData*> document);
|
||||
|
||||
void update();
|
||||
void countUpdatedRect();
|
||||
|
@ -1979,6 +1979,8 @@ void OverlayWidget::displayDocument(
|
||||
_doc = doc;
|
||||
if (_doc) {
|
||||
_docMedia = _doc->createMediaView();
|
||||
_docMedia->goodThumbnailWanted();
|
||||
_docMedia->thumbnailWanted(fileOrigin());
|
||||
}
|
||||
_rotation = _doc ? _doc->owner().mediaRotation().get(_doc) : 0;
|
||||
_themeCloudData = cloud;
|
||||
@ -1990,8 +1992,8 @@ void OverlayWidget::displayDocument(
|
||||
if (_doc->sticker()) {
|
||||
if (const auto image = _docMedia->getStickerLarge()) {
|
||||
_staticContent = image->pix(fileOrigin());
|
||||
} else if (_doc->hasThumbnail()) {
|
||||
_staticContent = _doc->thumbnail()->pixBlurred(
|
||||
} else if (const auto thumbnail = _docMedia->thumbnail()) {
|
||||
_staticContent = thumbnail->pixBlurred(
|
||||
fileOrigin(),
|
||||
_doc->dimensions.width(),
|
||||
_doc->dimensions.height());
|
||||
@ -2036,7 +2038,8 @@ void OverlayWidget::displayDocument(
|
||||
}
|
||||
} else {
|
||||
_doc->loadThumbnail(fileOrigin());
|
||||
int32 tw = _doc->thumbnail()->width(), th = _doc->thumbnail()->height();
|
||||
const auto tw = _docMedia->thumbnailSize().width();
|
||||
const auto th = _docMedia->thumbnailSize().height();
|
||||
if (!tw || !th) {
|
||||
_docThumbx = _docThumby = _docThumbw = 0;
|
||||
} else if (tw > th) {
|
||||
@ -2187,22 +2190,18 @@ void OverlayWidget::startStreamingPlayer() {
|
||||
void OverlayWidget::initStreamingThumbnail() {
|
||||
Expects(_doc != nullptr);
|
||||
|
||||
const auto media = _doc->activeMediaView();
|
||||
const auto good = media ? media->goodThumbnail() : nullptr;
|
||||
const auto good = _docMedia->goodThumbnail();
|
||||
const auto useGood = (good && good->loaded());
|
||||
const auto thumb = _doc->thumbnail();
|
||||
const auto useThumb = (thumb && thumb->loaded());
|
||||
|
||||
// #TODO optimize
|
||||
const auto blurred = media ? media->thumbnailInline() : nullptr;
|
||||
|
||||
const auto thumbnail = _docMedia->thumbnail();
|
||||
const auto useThumb = (thumbnail != nullptr);
|
||||
const auto blurred = _docMedia->thumbnailInline();
|
||||
if (good && !useGood) {
|
||||
good->load({});
|
||||
} else if (thumb && !useThumb) {
|
||||
thumb->load(fileOrigin());
|
||||
} else if (thumbnail) {
|
||||
thumbnail->load(fileOrigin());
|
||||
}
|
||||
const auto size = useGood ? good->size() : _doc->dimensions;
|
||||
if (!useGood && !thumb && !blurred) {
|
||||
if (!useGood && !thumbnail && !blurred) {
|
||||
return;
|
||||
} else if (size.isEmpty()) {
|
||||
return;
|
||||
@ -2214,7 +2213,7 @@ void OverlayWidget::initStreamingThumbnail() {
|
||||
_staticContent = (useGood
|
||||
? good
|
||||
: useThumb
|
||||
? thumb
|
||||
? thumbnail
|
||||
: blurred
|
||||
? blurred
|
||||
: Image::BlankMedia().get())->pixNoCache(
|
||||
@ -2827,9 +2826,9 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
|
||||
p.drawText(_docIconRect.x() + (_docIconRect.width() - _docExtWidth) / 2, _docIconRect.y() + st::mediaviewFileExtTop + st::mediaviewFileExtFont->ascent, _docExt);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (const auto thumbnail = _docMedia->thumbnail()) {
|
||||
int32 rf(cIntRetinaFactor());
|
||||
p.drawPixmap(_docIconRect.topLeft(), _doc->thumbnail()->pix(fileOrigin(), _docThumbw), QRect(_docThumbx * rf, _docThumby * rf, st::mediaviewFileIconSize * rf, st::mediaviewFileIconSize * rf));
|
||||
p.drawPixmap(_docIconRect.topLeft(), thumbnail->pix(fileOrigin(), _docThumbw), QRect(_docThumbx * rf, _docThumby * rf, st::mediaviewFileIconSize * rf, st::mediaviewFileIconSize * rf));
|
||||
}
|
||||
|
||||
paintRadialLoading(p, radial, radialOpacity);
|
||||
|
@ -1371,13 +1371,13 @@ QImage Pip::videoFrame(const FrameRequest &request) const {
|
||||
return _instance.frame(request);
|
||||
}
|
||||
const auto &cover = _instance.info().video.cover;
|
||||
|
||||
// #TODO optimize always use when available
|
||||
const auto media = _data->activeMediaView();
|
||||
const auto good = media ? media->goodThumbnail() : nullptr;
|
||||
const auto useGood = (good && good->loaded());
|
||||
const auto thumb = _data->thumbnail();
|
||||
const auto thumb = media ? media->thumbnail() : nullptr;
|
||||
const auto useThumb = (thumb && thumb->loaded());
|
||||
|
||||
// #TODO optimize always use when available
|
||||
const auto blurred = media ? media->thumbnailInline() : nullptr;
|
||||
|
||||
const auto state = !cover.isNull()
|
||||
|
@ -195,12 +195,13 @@ const style::RoundCheckbox &ItemBase::checkboxStyle() const {
|
||||
}
|
||||
|
||||
void ItemBase::ensureCheckboxCreated() {
|
||||
if (!_check) {
|
||||
const auto repaint = [=] {
|
||||
_parent->history()->session().data().requestItemRepaint(_parent);
|
||||
};
|
||||
_check = std::make_unique<Checkbox>(repaint, checkboxStyle());
|
||||
if (_check) {
|
||||
return;
|
||||
}
|
||||
const auto repaint = [=] {
|
||||
_parent->history()->session().data().requestItemRepaint(_parent);
|
||||
};
|
||||
_check = std::make_unique<Checkbox>(repaint, checkboxStyle());
|
||||
}
|
||||
|
||||
ItemBase::~ItemBase() = default;
|
||||
@ -255,11 +256,12 @@ void RadialProgressItem::radialAnimationCallback(crl::time now) const {
|
||||
}
|
||||
|
||||
void RadialProgressItem::ensureRadial() {
|
||||
if (!_radial) {
|
||||
_radial = std::make_unique<Ui::RadialAnimation>([=](crl::time now) {
|
||||
radialAnimationCallback(now);
|
||||
});
|
||||
if (_radial) {
|
||||
return;
|
||||
}
|
||||
_radial = std::make_unique<Ui::RadialAnimation>([=](crl::time now) {
|
||||
radialAnimationCallback(now);
|
||||
});
|
||||
}
|
||||
|
||||
void RadialProgressItem::checkRadialFinished() const {
|
||||
@ -438,8 +440,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||
|
||||
const auto selected = (selection == FullSelection);
|
||||
const auto blurred = _dataMedia->thumbnailInline();
|
||||
const auto thumbLoaded = _data->hasThumbnail()
|
||||
&& _data->thumbnail()->loaded();
|
||||
const auto thumbnail = _dataMedia->thumbnail();
|
||||
const auto goodLoaded = _dataMedia->goodThumbnail()
|
||||
&& _dataMedia->goodThumbnail()->loaded();
|
||||
|
||||
@ -454,14 +455,14 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||
const auto radial = isRadialAnimation();
|
||||
const auto radialOpacity = radial ? _radial->opacity() : 0.;
|
||||
|
||||
if ((blurred || thumbLoaded || goodLoaded)
|
||||
if ((blurred || thumbnail || goodLoaded)
|
||||
&& ((_pix.width() != _width * cIntRetinaFactor())
|
||||
|| (_pixBlurred && (thumbLoaded || goodLoaded)))) {
|
||||
|| (_pixBlurred && (thumbnail || goodLoaded)))) {
|
||||
auto size = _width * cIntRetinaFactor();
|
||||
auto img = goodLoaded
|
||||
? _dataMedia->goodThumbnail()->original()
|
||||
: thumbLoaded
|
||||
? _data->thumbnail()->original()
|
||||
: thumbnail
|
||||
? thumbnail->original()
|
||||
: Images::prepareBlur(blurred->original());
|
||||
if (img.width() == img.height()) {
|
||||
if (img.width() != size) {
|
||||
@ -475,7 +476,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||
img.setDevicePixelRatio(cRetinaFactor());
|
||||
|
||||
_pix = App::pixmapFromImageInPlace(std::move(img));
|
||||
_pixBlurred = !(thumbLoaded || goodLoaded);
|
||||
_pixBlurred = !(thumbnail || goodLoaded);
|
||||
}
|
||||
|
||||
if (_pix.isNull()) {
|
||||
@ -549,6 +550,7 @@ void Video::ensureDataMediaCreated() const {
|
||||
}
|
||||
_dataMedia = _data->createMediaView();
|
||||
_dataMedia->goodThumbnailWanted();
|
||||
_dataMedia->thumbnailWanted(parent()->fullId());
|
||||
}
|
||||
|
||||
float64 Video::dataProgress() const {
|
||||
@ -679,15 +681,17 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||
if (_data->hasThumbnail()) {
|
||||
ensureDataMediaCreated();
|
||||
}
|
||||
p.setPen(Qt::NoPen);
|
||||
const auto thumbLoaded = _data->hasThumbnail()
|
||||
&& _data->thumbnail()->loaded();
|
||||
const auto thumbnail = _dataMedia
|
||||
? _dataMedia->thumbnail()
|
||||
: nullptr;
|
||||
const auto blurred = _dataMedia
|
||||
? _dataMedia->thumbnailInline()
|
||||
: nullptr;
|
||||
if (thumbLoaded || blurred) {
|
||||
const auto thumb = thumbLoaded
|
||||
? _data->thumbnail()->pixCircled(
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
if (thumbnail || blurred) {
|
||||
const auto thumb = thumbnail
|
||||
? thumbnail->pixCircled(
|
||||
parent()->fullId(),
|
||||
inner.width(),
|
||||
inner.height())
|
||||
@ -707,7 +711,7 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||
? _openl
|
||||
: _savel;
|
||||
if (selected) {
|
||||
p.setBrush((thumbLoaded || blurred) ? st::msgDateImgBgSelected : st::msgFileInBgSelected);
|
||||
p.setBrush((thumbnail || blurred) ? st::msgDateImgBgSelected : st::msgFileInBgSelected);
|
||||
} else if (_data->hasThumbnail()) {
|
||||
auto over = ClickHandler::showAsActive(checkLink);
|
||||
p.setBrush(anim::brush(st::msgDateImgBg, st::msgDateImgBgOver, _a_iconOver.value(over ? 1. : 0.)));
|
||||
@ -931,8 +935,8 @@ Document::Document(
|
||||
|
||||
if (withThumb()) {
|
||||
_data->loadThumbnail(parent->fullId());
|
||||
auto tw = style::ConvertScale(_data->thumbnail()->width());
|
||||
auto th = style::ConvertScale(_data->thumbnail()->height());
|
||||
auto tw = style::ConvertScale(_data->thumbnailLocation().width());
|
||||
auto th = style::ConvertScale(_data->thumbnailLocation().height());
|
||||
if (tw > th) {
|
||||
_thumbw = (tw * _st.fileThumbSize) / th;
|
||||
} else {
|
||||
@ -1045,16 +1049,18 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
||||
if (clip.intersects(rthumb)) {
|
||||
if (wthumb) {
|
||||
ensureDataMediaCreated();
|
||||
const auto thumbLoaded = _data->thumbnail()->loaded();
|
||||
const auto thumbnail = _dataMedia->thumbnail();
|
||||
const auto thumbLoaded = (thumbnail != nullptr);
|
||||
const auto blurred = _dataMedia->thumbnailInline();
|
||||
if (thumbLoaded || blurred) {
|
||||
if (_thumb.isNull() || (thumbLoaded && !_thumbLoaded)) {
|
||||
_thumbLoaded = thumbLoaded;
|
||||
auto options = Images::Option::Smooth | Images::Option::None;
|
||||
if (!_thumbLoaded) options |= Images::Option::Blurred;
|
||||
_thumb = (_thumbLoaded
|
||||
? _data->thumbnail()
|
||||
: blurred)->pixNoCache(parent()->fullId(), _thumbw * cIntRetinaFactor(), 0, options, _st.fileThumbSize, _st.fileThumbSize);
|
||||
if (thumbnail || blurred) {
|
||||
if (_thumb.isNull() || (thumbnail && !_thumbLoaded)) {
|
||||
_thumbLoaded = (thumbnail != nullptr);
|
||||
auto options = Images::Option::Smooth
|
||||
| (_thumbLoaded
|
||||
? Images::Option::None
|
||||
: Images::Option::Blurred);
|
||||
const auto image = thumbnail ? thumbnail : blurred;
|
||||
_thumb = image->pixNoCache(parent()->fullId(), _thumbw * cIntRetinaFactor(), 0, options, _st.fileThumbSize, _st.fileThumbSize);
|
||||
}
|
||||
p.drawPixmap(rthumb.topLeft(), _thumb);
|
||||
} else {
|
||||
@ -1307,6 +1313,7 @@ void Document::ensureDataMediaCreated() const {
|
||||
return;
|
||||
}
|
||||
_dataMedia = _data->createMediaView();
|
||||
_dataMedia->thumbnailWanted(parent()->fullId());
|
||||
}
|
||||
|
||||
float64 Document::dataProgress() const {
|
||||
@ -1332,8 +1339,6 @@ bool Document::iconAnimated() const {
|
||||
bool Document::withThumb() const {
|
||||
return !_data->isSong()
|
||||
&& _data->hasThumbnail()
|
||||
&& _data->thumbnail()->width()
|
||||
&& _data->thumbnail()->height()
|
||||
&& !Data::IsExecutableName(_data->filename());
|
||||
}
|
||||
|
||||
@ -1465,9 +1470,9 @@ Link::Link(
|
||||
th = style::ConvertScale(_page->photo->height());
|
||||
} else if (_page && _page->document && _page->document->hasThumbnail()) {
|
||||
_page->document->loadThumbnail(parent->fullId());
|
||||
|
||||
tw = style::ConvertScale(_page->document->thumbnail()->width());
|
||||
th = style::ConvertScale(_page->document->thumbnail()->height());
|
||||
const auto &location = _page->document->thumbnailLocation();
|
||||
tw = style::ConvertScale(location.width());
|
||||
th = style::ConvertScale(location.height());
|
||||
}
|
||||
if (tw > st::linksPhotoSize) {
|
||||
if (th > tw) {
|
||||
@ -1559,10 +1564,13 @@ void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const P
|
||||
}
|
||||
p.drawPixmapLeft(pixLeft, pixTop, _width, pix);
|
||||
} else if (_page && _page->document && _page->document->hasThumbnail()) {
|
||||
auto roundRadius = _page->document->isVideoMessage()
|
||||
? ImageRoundRadius::Ellipse
|
||||
: ImageRoundRadius::Small;
|
||||
p.drawPixmapLeft(pixLeft, pixTop, _width, _page->document->thumbnail()->pixSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, roundRadius));
|
||||
ensureDocumentMediaCreated();
|
||||
if (const auto thumbnail = _documentMedia->thumbnail()) {
|
||||
auto roundRadius = _page->document->isVideoMessage()
|
||||
? ImageRoundRadius::Ellipse
|
||||
: ImageRoundRadius::Small;
|
||||
p.drawPixmapLeft(pixLeft, pixTop, _width, thumbnail->pixSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, roundRadius));
|
||||
}
|
||||
} else {
|
||||
const auto index = _letter.isEmpty()
|
||||
? 0
|
||||
@ -1638,6 +1646,14 @@ void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const P
|
||||
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
||||
}
|
||||
|
||||
void Link::ensureDocumentMediaCreated() {
|
||||
if (_documentMedia) {
|
||||
return;
|
||||
}
|
||||
_documentMedia = _page->document->createMediaView();
|
||||
_documentMedia->thumbnailWanted(parent()->fullId());
|
||||
}
|
||||
|
||||
TextState Link::getState(
|
||||
QPoint point,
|
||||
StateRequest request) const {
|
||||
|
@ -364,11 +364,14 @@ protected:
|
||||
const style::RoundCheckbox &checkboxStyle() const override;
|
||||
|
||||
private:
|
||||
void ensureDocumentMediaCreated();
|
||||
|
||||
ClickHandlerPtr _photol;
|
||||
|
||||
QString _title, _letter;
|
||||
int _titlew = 0;
|
||||
WebPageData *_page = nullptr;
|
||||
std::shared_ptr<Data::DocumentMedia> _documentMedia;
|
||||
int _pixw = 0;
|
||||
int _pixh = 0;
|
||||
Ui::Text::String _text = { st::msgMinWidth };
|
||||
|
@ -44,9 +44,7 @@ FileLoader::FileLoader(
|
||||
}
|
||||
|
||||
FileLoader::~FileLoader() {
|
||||
if (!_finished) {
|
||||
cancel();
|
||||
}
|
||||
Expects(_finished);
|
||||
}
|
||||
|
||||
Main::Session &FileLoader::session() const {
|
||||
|
@ -78,6 +78,12 @@ mtpFileLoader::mtpFileLoader(
|
||||
{ location }) {
|
||||
}
|
||||
|
||||
mtpFileLoader::~mtpFileLoader() {
|
||||
if (!_finished) {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
||||
Data::FileOrigin mtpFileLoader::fileOrigin() const {
|
||||
return DownloadMtprotoTask::fileOrigin();
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading,
|
||||
uint8 cacheTag);
|
||||
~mtpFileLoader();
|
||||
|
||||
Data::FileOrigin fileOrigin() const override;
|
||||
uint64 objId() const override;
|
||||
|
@ -453,7 +453,9 @@ webFileLoader::webFileLoader(
|
||||
}
|
||||
|
||||
webFileLoader::~webFileLoader() {
|
||||
cancelRequest();
|
||||
if (!_finished) {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
||||
QString webFileLoader::url() const {
|
||||
|
@ -3945,11 +3945,12 @@ void importOldRecentStickers() {
|
||||
attributes,
|
||||
mime,
|
||||
QByteArray(),
|
||||
ImagePtr(),
|
||||
StorageImageLocation(),
|
||||
dc,
|
||||
size,
|
||||
StorageImageLocation());
|
||||
if (!doc->sticker()) continue;
|
||||
size);
|
||||
if (!doc->sticker()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value > 0) {
|
||||
def.stickers.push_back(doc);
|
||||
|
@ -46,14 +46,10 @@ void Document::writeToStream(QDataStream &stream, DocumentData *document) {
|
||||
stream << qint32(StickerSetTypeEmpty);
|
||||
} break;
|
||||
}
|
||||
writeStorageImageLocation(stream, document->sticker()->loc);
|
||||
writeStorageImageLocation(stream, document->_thumbnailLocation);
|
||||
} else {
|
||||
stream << qint32(document->getDuration());
|
||||
if (const auto thumb = document->thumbnail()) {
|
||||
writeStorageImageLocation(stream, thumb->location());
|
||||
} else {
|
||||
writeStorageImageLocation(stream, StorageImageLocation());
|
||||
}
|
||||
writeStorageImageLocation(stream, document->thumbnailLocation());
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,10 +143,9 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream &
|
||||
attributes,
|
||||
mime,
|
||||
QByteArray(),
|
||||
Images::Create(*thumb),
|
||||
*thumb,
|
||||
dc,
|
||||
size,
|
||||
*thumb);
|
||||
size);
|
||||
}
|
||||
|
||||
DocumentData *Document::readStickerFromStream(int streamAppVersion, QDataStream &stream, const StickerSetInfo &info) {
|
||||
@ -176,18 +171,12 @@ int Document::sizeInStream(DocumentData *document) {
|
||||
if (auto sticker = document->sticker()) { // type == StickerDocument
|
||||
// + altlen + alt + type-of-set
|
||||
result += stringSize(sticker->alt) + sizeof(qint32);
|
||||
// + sticker loc
|
||||
result += Serialize::storageImageLocationSize(document->sticker()->loc);
|
||||
} else {
|
||||
// + duration
|
||||
result += sizeof(qint32);
|
||||
// + thumb loc
|
||||
if (const auto thumb = document->thumbnail()) {
|
||||
result += Serialize::storageImageLocationSize(thumb->location());
|
||||
} else {
|
||||
result += Serialize::storageImageLocationSize(StorageImageLocation());
|
||||
}
|
||||
}
|
||||
// + thumb loc
|
||||
result += Serialize::storageImageLocationSize(document->thumbnailLocation());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -63,7 +63,9 @@ StreamedFileDownloader::StreamedFileDownloader(
|
||||
}
|
||||
|
||||
StreamedFileDownloader::~StreamedFileDownloader() {
|
||||
cancelHook();
|
||||
if (!_finished) {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
||||
uint64 StreamedFileDownloader::objId() const {
|
||||
|
@ -116,6 +116,7 @@ void MediaPreviewWidget::showPreview(
|
||||
_photo = nullptr;
|
||||
_document = document;
|
||||
_documentMedia = _document->createMediaView();
|
||||
_documentMedia->thumbnailWanted(_origin);
|
||||
fillEmojiString();
|
||||
resetGifAndCache();
|
||||
}
|
||||
@ -255,9 +256,9 @@ QPixmap MediaPreviewWidget::currentImage() const {
|
||||
_cacheStatus = CacheLoaded;
|
||||
} else if (_cacheStatus != CacheThumbLoaded
|
||||
&& _document->hasThumbnail()
|
||||
&& _document->thumbnail()->loaded()) {
|
||||
&& _documentMedia->thumbnail()) {
|
||||
QSize s = currentDimensions();
|
||||
_cache = _document->thumbnail()->pixBlurred(_origin, s.width(), s.height());
|
||||
_cache = _documentMedia->thumbnail()->pixBlurred(_origin, s.width(), s.height());
|
||||
_cacheStatus = CacheThumbLoaded;
|
||||
}
|
||||
}
|
||||
@ -280,14 +281,13 @@ QPixmap MediaPreviewWidget::currentImage() const {
|
||||
if (_cacheStatus != CacheThumbLoaded
|
||||
&& _document->hasThumbnail()) {
|
||||
QSize s = currentDimensions();
|
||||
if (_document->thumbnail()->loaded()) {
|
||||
_cache = _document->thumbnail()->pixBlurred(_origin, s.width(), s.height());
|
||||
const auto thumbnail = _documentMedia->thumbnail();
|
||||
if (thumbnail) {
|
||||
_cache = thumbnail->pixBlurred(_origin, s.width(), s.height());
|
||||
_cacheStatus = CacheThumbLoaded;
|
||||
} else if (const auto blurred = _documentMedia->thumbnailInline()) {
|
||||
_cache = _document->thumbnail()->pixBlurred(_origin, s.width(), s.height());
|
||||
_cache = blurred->pixBlurred(_origin, s.width(), s.height());
|
||||
_cacheStatus = CacheThumbLoaded;
|
||||
} else {
|
||||
_document->thumbnail()->load(_origin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user