Keep document byte data only in DocumentMedia.

This commit is contained in:
John Preston 2020-04-10 17:18:51 +04:00
parent 97bab388ea
commit 40f12a2584
26 changed files with 280 additions and 241 deletions

View file

@ -433,7 +433,7 @@ void BackgroundPreviewBox::prepare() {
_paper.loadThumbnail();
_paper.loadDocument();
if (_paper.document() && _paper.document()->loading()) {
_radial.start(_paper.document()->progress());
_radial.start(_media->progress());
}
if (_paper.thumbnail() && !_paper.isPattern()) {
createBlurCheckbox();
@ -636,7 +636,7 @@ void BackgroundPreviewBox::radialAnimationCallback(crl::time now) {
const auto document = _paper.document();
const auto wasAnimating = _radial.animating();
const auto updated = _radial.update(
document->progress(),
_media->progress(),
!document->loading(),
now);
if ((wasAnimating || _radial.animating())
@ -746,7 +746,7 @@ void BackgroundPreviewBox::checkLoadedDocument() {
});
};
_generating = Data::ReadImageAsync(
document,
_media.get(),
Window::Theme::ProcessBackgroundImage,
generateCallback);
}

View file

@ -944,7 +944,9 @@ void StickersBox::Inner::paintRowThumbnail(
void StickersBox::Inner::validateLottieAnimation(not_null<Row*> set) {
if (set->lottie
|| !Stickers::HasLottieThumbnail(set->thumbnail, set->sticker)) {
|| !Stickers::HasLottieThumbnail(
set->thumbnail,
set->stickerMedia.get())) {
return;
}
auto player = Stickers::LottieThumbnail(

View file

@ -1028,15 +1028,13 @@ void GifsListWidget::showPreview() {
auto layout = _rows[row].items[col];
if (const auto w = App::wnd()) {
if (const auto previewDocument = layout->getPreviewDocument()) {
w->showMediaPreview(
_previewShown = w->showMediaPreview(
Data::FileOriginSavedGifs(),
previewDocument);
_previewShown = true;
} else if (const auto previewPhoto = layout->getPreviewPhoto()) {
w->showMediaPreview(
_previewShown = w->showMediaPreview(
Data::FileOrigin(),
previewPhoto);
_previewShown = true;
}
}
}

View file

@ -1220,7 +1220,8 @@ not_null<Lottie::Animation*> LottieAnimationFromDocument(
bool HasLottieThumbnail(
ImagePtr thumbnail,
not_null<DocumentData*> sticker) {
not_null<Data::DocumentMedia*> media) {
const auto document = media->owner();
if (thumbnail) {
if (!thumbnail->loaded()) {
return false;
@ -1230,15 +1231,15 @@ bool HasLottieThumbnail(
return location.valid()
&& location.type() == StorageFileLocation::Type::StickerSetThumb
&& !bytes.isEmpty();
} else if (const auto info = sticker->sticker()) {
} else if (const auto info = document->sticker()) {
if (!info->animated) {
return false;
}
sticker->automaticLoad(sticker->stickerSetOrigin(), nullptr);
if (!sticker->loaded()) {
document->automaticLoad(document->stickerSetOrigin(), nullptr);
if (!media->loaded()) {
return false;
}
return sticker->bigFileBaseCacheKey().has_value();
return document->bigFileBaseCacheKey().has_value();
}
return false;
}

View file

@ -160,7 +160,7 @@ enum class LottieSize : uchar {
[[nodiscard]] bool HasLottieThumbnail(
ImagePtr thumbnail,
not_null<DocumentData*> sticker);
not_null<Data::DocumentMedia*> media);
[[nodiscard]] std::unique_ptr<Lottie::SinglePlayer> LottieThumbnail(
ImagePtr thumbnail,
not_null<Data::DocumentMedia*> media,

View file

@ -701,7 +701,9 @@ void StickersListWidget::Footer::paintSearchIcon(Painter &p) const {
void StickersListWidget::Footer::validateIconLottieAnimation(
const StickerIcon &icon) {
if (icon.lottie
|| !Stickers::HasLottieThumbnail(icon.thumbnail, icon.sticker)) {
|| !Stickers::HasLottieThumbnail(
icon.thumbnail,
icon.stickerMedia.get())) {
return;
}
auto player = Stickers::LottieThumbnail(

View file

@ -44,17 +44,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace {
// Updated Mar 3, 2020: Increase the size of the memory cache for media, to prevent items still being displayed from being unloaded.
constexpr auto kMemoryForCache = 128 * 1024 * 1024; // was 32, updated to 128
const auto kAnimatedStickerDimensions = QSize(512, 512);
Core::MediaActiveCache<DocumentData> &ActiveCache() {
static auto Instance = Core::MediaActiveCache<DocumentData>(
kMemoryForCache,
[](DocumentData *document) { document->unload(); });
return Instance;
}
QString JoinStringList(const QStringList &list, const QString &separator) {
const auto count = list.size();
if (!count) {
@ -320,11 +311,12 @@ void DocumentOpenClickHandler::Open(
}
LaunchWithWarning(location.name(), context);
};
const auto media = data->createMediaView();
const auto &location = data->location(true);
if (data->isTheme() && data->loaded(true)) {
if (data->isTheme() && media->loaded(true)) {
Core::App().showDocument(data, context);
location.accessDisable();
} else if (data->canBePlayed()) {
} else if (media->canBePlayed()) {
if (data->isAudioFile()
|| data->isVoiceMessage()
|| data->isVideoMessage()) {
@ -458,7 +450,6 @@ DocumentData::DocumentData(not_null<Data::Session*> owner, DocumentId id)
DocumentData::~DocumentData() {
destroyLoader();
unload();
ActiveCache().remove(this);
}
Data::Session &DocumentData::owner() const {
@ -578,7 +569,6 @@ void DocumentData::validateLottieSticker() {
}
void DocumentData::setDataAndCache(const QByteArray &data) {
_data = data;
if (const auto media = activeMediaView()) {
media->setBytes(data);
}
@ -744,16 +734,13 @@ void DocumentData::unload() {
//
//_thumbnail->unload();
_replyPreview = nullptr;
if (!_data.isEmpty()) {
ActiveCache().decrement(_data.size());
_data.clear();
}
}
void DocumentData::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
if (status != FileReady || loaded() || cancelled()) {
const auto media = activeMediaView();
if (status != FileReady || !media || media->loaded() || cancelled()) {
return;
} else if (!item && type != StickerDocument && !isAnimation()) {
return;
@ -794,10 +781,6 @@ void DocumentData::automaticLoadSettingsChanged() {
_flags &= ~Flag::DownloadCancelled;
}
bool DocumentData::loaded(bool check) const {
return !rawBytes().isEmpty() || !filepath(check).isEmpty();
}
void DocumentData::finishLoad() {
const auto guard = gsl::finally([&] {
destroyLoader();
@ -807,18 +790,11 @@ void DocumentData::finishLoad() {
return;
}
setLocation(FileLocation(_loader->fileName()));
ActiveCache().decrement(_data.size());
_data = _loader->bytes();
ActiveCache().increment(_data.size());
setGoodThumbnailDataReady();
if (const auto media = activeMediaView()) {
media->setBytes(_loader->bytes());
media->checkStickerLarge(_loader.get());
}
if (!_data.isEmpty()) {
ActiveCache().up(this);
}
}
void DocumentData::destroyLoader() const {
@ -854,7 +830,7 @@ float64 DocumentData::progress() const {
}
return 0.;
}
return loading() ? _loader->currentProgress() : (loaded() ? 1. : 0.);
return loading() ? _loader->currentProgress() : 0.;
}
int DocumentData::loadOffset() const {
@ -909,13 +885,13 @@ void DocumentData::save(
const QString &toFile,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
if (loaded(true)) {
if (const auto media = activeMediaView(); media->loaded(true)) {
auto &l = location(true);
if (!toFile.isEmpty()) {
if (!rawBytes().isEmpty()) {
if (!media->bytes().isEmpty()) {
QFile f(toFile);
f.open(QIODevice::WriteOnly);
f.write(rawBytes());
f.write(media->bytes());
f.close();
setLocation(FileLocation(toFile));
@ -1108,13 +1084,6 @@ QByteArray documentWaveformEncode5bit(const VoiceWaveform &waveform) {
return result;
}
QByteArray DocumentData::rawBytes() const {
if (!_data.isEmpty()) {
ActiveCache().up(const_cast<DocumentData*>(this));
}
return _data;
}
const FileLocation &DocumentData::location(bool check) const {
if (check && !_location.check()) {
const auto location = Local::readFileLocation(mediaKey());
@ -1272,12 +1241,6 @@ bool DocumentData::canBeStreamed() const {
return hasRemoteLocation() && supportsStreaming();
}
bool DocumentData::canBePlayed() const {
return !(_flags & Flag::StreamingPlaybackFailed)
&& useStreamingLoader()
&& (loaded() || canBeStreamed());
}
void DocumentData::setInappPlaybackFailed() {
_flags |= Flag::StreamingPlaybackFailed;
}
@ -1294,9 +1257,10 @@ auto DocumentData::createStreamingLoader(
return nullptr;
}
if (!forceRemoteLoader) {
const auto media = activeMediaView();
const auto &location = this->location(true);
if (!rawBytes().isEmpty()) {
return Media::Streaming::MakeBytesLoader(rawBytes());
if (media && !media->bytes().isEmpty()) {
return Media::Streaming::MakeBytesLoader(media->bytes());
} else if (!location.isEmpty() && location.accessEnable()) {
auto result = Media::Streaming::MakeFileLoader(location.name());
location.accessDisable();
@ -1574,15 +1538,10 @@ void DocumentData::collectLocalData(not_null<DocumentData*> local) {
}
_owner->cache().copyIfEmpty(local->cacheKey(), cacheKey());
if (!local->_data.isEmpty()) {
ActiveCache().decrement(_data.size());
_data = local->_data;
const auto localMedia = local->activeMediaView();
if (!localMedia->bytes().isEmpty()) {
if (const auto media = activeMediaView()) {
media->setBytes(local->_data);
}
ActiveCache().increment(_data.size());
if (!_data.isEmpty()) {
ActiveCache().up(this);
media->setBytes(localMedia->bytes());
}
}
if (!local->_location.inMediaCache() && !local->_location.isEmpty()) {
@ -1672,13 +1631,13 @@ website ws wsc wsf wsh xbap xll xnk xs");
}
base::binary_guard ReadImageAsync(
not_null<DocumentData*> document,
not_null<Data::DocumentMedia*> media,
FnMut<QImage(QImage)> postprocess,
FnMut<void(QImage&&)> done) {
auto result = base::binary_guard();
crl::async([
bytes = document->rawBytes(),
path = document->filepath(),
bytes = media->bytes(),
path = media->owner()->filepath(),
postprocess = std::move(postprocess),
guard = result.make_guard(),
callback = std::move(done)

View file

@ -100,7 +100,6 @@ public:
const HistoryItem *item);
void automaticLoadSettingsChanged();
[[nodiscard]] bool loaded(bool check = false) const;
[[nodiscard]] bool loading() const;
[[nodiscard]] QString loadingFilePath() const;
[[nodiscard]] bool displayLoading() const;
@ -120,7 +119,6 @@ public:
void setWaitingForAlbum();
[[nodiscard]] bool waitingForAlbum() const;
[[nodiscard]] QByteArray rawBytes() const;
[[nodiscard]] const FileLocation &location(bool check = false) const;
void setLocation(const FileLocation &loc);
@ -225,12 +223,12 @@ public:
const QString &songPerformer);
[[nodiscard]] QString composeNameString() const;
[[nodiscard]] bool canBePlayed() const;
[[nodiscard]] bool canBeStreamed() const;
[[nodiscard]] auto createStreamingLoader(
Data::FileOrigin origin,
bool forceRemoteLoader) const
-> std::unique_ptr<Media::Streaming::Loader>;
[[nodiscard]] bool useStreamingLoader() const;
void setInappPlaybackFailed();
[[nodiscard]] bool inappPlaybackFailed() const;
@ -291,7 +289,6 @@ private:
void handleLoaderUpdates();
void destroyLoader() const;
[[nodiscard]] bool useStreamingLoader() const;
bool saveFromDataChecked();
// Two types of location: from MTProto by dc+access or from web by url
@ -312,7 +309,6 @@ private:
not_null<Data::Session*> _owner;
FileLocation _location;
QByteArray _data;
std::unique_ptr<DocumentAdditionalData> _additional;
int32 _duration = -1;
mutable Flags _flags = kStreamingSupportedUnknown;
@ -440,7 +436,7 @@ QString FileExtension(const QString &filepath);
bool IsValidMediaFile(const QString &filepath);
bool IsExecutableName(const QString &filepath);
base::binary_guard ReadImageAsync(
not_null<DocumentData*> document,
not_null<Data::DocumentMedia*> media,
FnMut<QImage(QImage)> postprocess,
FnMut<void(QImage&&)> done);

View file

@ -82,8 +82,7 @@ enum class FileType {
} // namespace
DocumentMedia::DocumentMedia(not_null<DocumentData*> owner)
: _owner(owner)
, _bytes(owner->rawBytes()) {
: _owner(owner) {
}
DocumentMedia::~DocumentMedia() = default;
@ -140,8 +139,7 @@ void DocumentMedia::checkStickerLarge() {
if (data->animated || !loaded()) {
return;
}
const auto bytes = _owner->rawBytes();
if (bytes.isEmpty()) {
if (_bytes.isEmpty()) {
const auto &loc = _owner->location(true);
if (loc.accessEnable()) {
_sticker = std::make_unique<Image>(
@ -150,11 +148,11 @@ void DocumentMedia::checkStickerLarge() {
}
} else {
auto format = QByteArray();
auto image = App::readImage(bytes, &format, false);
auto image = App::readImage(_bytes, &format, false);
_sticker = std::make_unique<Image>(
std::make_unique<Images::LocalFileSource>(
QString(),
bytes,
_bytes,
format,
std::move(image)));
}
@ -171,7 +169,19 @@ QByteArray DocumentMedia::bytes() const {
}
bool DocumentMedia::loaded(bool check) const {
return !_bytes.isEmpty() || _owner->loaded(check);// checkLoadedTo(this);
return !_bytes.isEmpty() || !_owner->filepath(check).isEmpty();
}
float64 DocumentMedia::progress() const {
return (owner()->uploading() || owner()->loading())
? owner()->progress()
: (loaded() ? 1. : 0.);
}
bool DocumentMedia::canBePlayed() const {
return !owner()->inappPlaybackFailed()
&& owner()->useStreamingLoader()
&& (loaded() || owner()->canBeStreamed());
}
void DocumentMedia::checkStickerSmall() {
@ -203,18 +213,19 @@ void DocumentMedia::checkStickerLarge(not_null<FileLoader*> loader) {
if (_owner->sticker()
&& !_sticker
&& !loader->imageData().isNull()
&& !_owner->rawBytes().isEmpty()) {
&& !_bytes.isEmpty()) {
_sticker = std::make_unique<Image>(
std::make_unique<Images::LocalFileSource>(
QString(),
_owner->rawBytes(),
_bytes,
loader->imageFormat(),
loader->imageData()));
}
}
void DocumentMedia::GenerateGoodThumbnail(not_null<DocumentData*> document) {
const auto data = document->rawBytes();
void DocumentMedia::GenerateGoodThumbnail(
not_null<DocumentData*> document,
QByteArray data) {
const auto type = document->isWallPaper()
? FileType::WallPaper
: document->isTheme()
@ -282,8 +293,9 @@ void DocumentMedia::ReadOrGenerateThumbnail(
const auto active = document->activeMediaView();
const auto got = [=](QByteArray value) {
if (value.isEmpty()) {
const auto bytes = active ? active->bytes() : QByteArray();
crl::on_main(guard, [=] {
GenerateGoodThumbnail(document);
GenerateGoodThumbnail(document, bytes);
});
} else if (active) {
crl::async([=] {

View file

@ -35,6 +35,8 @@ public:
void setBytes(const QByteArray &bytes);
[[nodiscard]] QByteArray bytes() const;
[[nodiscard]] bool loaded(bool check = false) const;
[[nodiscard]] float64 progress() const;
[[nodiscard]] bool canBePlayed() const;
// For DocumentData.
static void CheckGoodThumbnail(not_null<DocumentData*> document);
@ -47,7 +49,9 @@ private:
using Flags = base::flags<Flag>;
static void ReadOrGenerateThumbnail(not_null<DocumentData*> document);
static void GenerateGoodThumbnail(not_null<DocumentData*> document);
static void GenerateGoodThumbnail(
not_null<DocumentData*> document,
QByteArray data);
const not_null<DocumentData*> _owner;
std::unique_ptr<Image> _goodThumbnail;

View file

@ -85,7 +85,8 @@ Document::Document(
}
float64 Document::dataProgress() const {
return _data->progress();
ensureDataMediaCreated();
return _dataMedia->progress();
}
bool Document::dataFinished() const {
@ -93,7 +94,8 @@ bool Document::dataFinished() const {
}
bool Document::dataLoaded() const {
return _dataMedia ? _dataMedia->loaded() : _data->loaded();
ensureDataMediaCreated();
return _dataMedia->loaded();
}
void Document::createComponents(bool caption) {
@ -240,12 +242,14 @@ QSize Document::countCurrentSize(int newWidth) {
void Document::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
ensureDataMediaCreated();
const auto cornerDownload = downloadInCorner();
if (!_data->canBePlayed()) {
if (!_dataMedia->canBePlayed()) {
_data->automaticLoad(_realParent->fullId(), _parent->data());
}
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
bool loaded = dataLoaded(), displayLoading = _data->displayLoading();
bool selected = (selection == FullSelection);
int captionw = width() - st::msgPadding.left() - st::msgPadding.right();
@ -254,7 +258,7 @@ void Document::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
if (displayLoading) {
ensureAnimation();
if (!_animation->radial.animating()) {
_animation->radial.start(_data->progress());
_animation->radial.start(dataProgress());
}
}
const auto showPause = updateStatusText();
@ -263,8 +267,6 @@ void Document::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
int nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0;
if (auto thumbed = Get<HistoryDocumentThumbed>()) {
ensureDataMediaCreated();
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
nametop = st::msgFileThumbNameTop - topMinus;
nameright = st::msgFileThumbPadding.left();
@ -328,7 +330,7 @@ void Document::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
if (_data->status != FileUploadFailed) {
const auto &lnk = (_data->loading() || _data->uploading())
? thumbed->_linkcancell
: _data->loaded()
: dataLoaded()
? thumbed->_linkopenwithl
: thumbed->_linksavel;
bool over = ClickHandler::showAsActive(lnk);
@ -361,8 +363,8 @@ void Document::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
return &(outbg ? (selected ? st::historyFileOutCancelSelected : st::historyFileOutCancel) : (selected ? st::historyFileInCancelSelected : st::historyFileInCancel));
} else if (showPause) {
return &(outbg ? (selected ? st::historyFileOutPauseSelected : st::historyFileOutPause) : (selected ? st::historyFileInPauseSelected : st::historyFileInPause));
} else if (loaded || _data->canBePlayed()) {
if (_data->canBePlayed()) {
} else if (loaded || _dataMedia->canBePlayed()) {
if (_dataMedia->canBePlayed()) {
return &(outbg ? (selected ? st::historyFileOutPlaySelected : st::historyFileOutPlay) : (selected ? st::historyFileInPlaySelected : st::historyFileInPlay));
} else if (_data->isImage()) {
return &(outbg ? (selected ? st::historyFileOutImageSelected : st::historyFileOutImage) : (selected ? st::historyFileInImageSelected : st::historyFileInImage));
@ -379,7 +381,9 @@ void Document::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
_animation->radial.draw(p, rinner, st::msgFileRadialLine, fg);
}
drawCornerDownload(p, selected);
if (!loaded) {
drawCornerDownload(p, selected);
}
}
auto namewidth = width() - nameleft - nameright;
auto statuswidth = namewidth;
@ -522,7 +526,7 @@ bool Document::downloadInCorner() const {
}
void Document::drawCornerDownload(Painter &p, bool selected) const {
if (_data->loaded() || !downloadInCorner()) {
if (!downloadInCorner()) {
return;
}
auto outbg = _parent->hasOutLayout();
@ -562,7 +566,7 @@ TextState Document::cornerDownloadTextState(
QPoint point,
StateRequest request) const {
auto result = TextState(_parent);
if (!downloadInCorner() || _data->loaded()) {
if (!downloadInCorner()) {
return result;
}
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
@ -583,7 +587,8 @@ TextState Document::textState(QPoint point, StateRequest request) const {
return result;
}
bool loaded = _data->loaded();
ensureDataMediaCreated();
bool loaded = dataLoaded();
bool showPause = updateStatusText();
@ -606,7 +611,7 @@ TextState Document::textState(QPoint point, StateRequest request) const {
if (style::rtlrect(nameleft, linktop, thumbed->_linkw, st::semiboldFont->height, width()).contains(point)) {
result.link = (_data->loading() || _data->uploading())
? thumbed->_linkcancell
: _data->loaded()
: dataLoaded()
? thumbed->_linkopenwithl
: thumbed->_linksavel;
return result;
@ -618,8 +623,10 @@ TextState Document::textState(QPoint point, StateRequest request) const {
nametop = st::msgFileNameTop - topMinus;
bottom = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom() - topMinus;
if (const auto state = cornerDownloadTextState(point, request); state.link) {
return state;
if (!loaded) {
if (const auto state = cornerDownloadTextState(point, request); state.link) {
return state;
}
}
QRect inner(style::rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, st::msgFileSize, st::msgFileSize, width()));
if ((_data->loading() || _data->uploading()) && inner.contains(point) && !downloadInCorner()) {
@ -663,7 +670,7 @@ TextState Document::textState(QPoint point, StateRequest request) const {
&& (!_data->loading() || downloadInCorner())
&& !_data->uploading()
&& !_data->isNull()) {
if (loaded || _data->canBePlayed()) {
if (loaded || _dataMedia->canBePlayed()) {
result.link = _openl;
} else {
result.link = _savel;
@ -755,7 +762,7 @@ bool Document::updateStatusText() const {
statusSize = _data->uploadingData->offset;
} else if (_data->loading()) {
statusSize = _data->loadOffset();
} else if (_data->loaded()) {
} else if (dataLoaded()) {
statusSize = FileStatusSizeLoaded;
} else {
statusSize = FileStatusSizeReady;

View file

@ -24,7 +24,7 @@ class String;
namespace HistoryView {
class Document
class Document final
: public File
, public RuntimeComposer<Document> {
public:

View file

@ -265,12 +265,14 @@ bool Gif::autoplayEnabled() const {
void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
ensureDataMediaCreated();
const auto item = _parent->data();
const auto loaded = dataLoaded();
const auto displayLoading = item->isSending() || _data->displayLoading();
const auto selected = (selection == FullSelection);
const auto autoPaused = App::wnd()->sessionController()->isGifPausedAtLeastFor(Window::GifPauseReason::Any);
const auto cornerDownload = downloadInCorner();
const auto canBePlayed = _data->canBePlayed();
const auto canBePlayed = _dataMedia->canBePlayed();
const auto autoplay = autoplayEnabled()
&& canBePlayed
&& CanPlayInline(_data);
@ -449,12 +451,12 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
if (radial
|| (!streamingMode
&& ((!_data->loaded() && !_data->loading()) || !autoplay))) {
&& ((!loaded && !_data->loading()) || !autoplay))) {
const auto radialOpacity = (item->isSending() || _data->uploading())
? 1.
: streamedForWaiting
? streamedForWaiting->waitingOpacity()
: (radial && _data->loaded())
: (radial && loaded)
? _animation->radial.opacity()
: 1.;
auto inner = QRect(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
@ -479,7 +481,7 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
const auto icon = [&]() -> const style::icon * {
if (streamingMode && !_data->uploading()) {
return nullptr;
} else if ((_data->loaded() || canBePlayed) && (!radial || cornerDownload)) {
} else if ((loaded || canBePlayed) && (!radial || cornerDownload)) {
return &(selected ? st::historyFileThumbPlaySelected : st::historyFileThumbPlay);
} else if (radial || _data->loading()) {
if (!item->isSending() || _data->uploading()) {
@ -640,7 +642,7 @@ void Gif::drawCornerStatus(Painter &p, bool selected, QPoint position) const {
: _statusText;
const auto padding = st::msgDateImgPadding;
const auto radial = _animation && _animation->radial.animating();
const auto cornerDownload = downloadInCorner() && !_data->loaded() && !_data->loadedInMediaCache();
const auto cornerDownload = downloadInCorner() && !dataLoaded() && !_data->loadedInMediaCache();
const auto cornerMute = _streamed && _data->isVideoFile() && !cornerDownload;
const auto addLeft = cornerDownload ? (st::historyVideoDownloadSize + 2 * padding.y()) : 0;
const auto addRight = cornerMute ? st::historyVideoMuteSize : 0;
@ -682,7 +684,7 @@ TextState Gif::cornerStatusTextState(
StateRequest request,
QPoint position) const {
auto result = TextState(_parent);
if (!needCornerStatusDisplay() || !downloadInCorner() || _data->loaded()) {
if (!needCornerStatusDisplay() || !downloadInCorner() || dataLoaded()) {
return result;
}
const auto padding = st::msgDateImgPadding;
@ -702,6 +704,7 @@ TextState Gif::textState(QPoint point, StateRequest request) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
return result;
}
ensureDataMediaCreated();
auto paintx = 0, painty = 0, paintw = width(), painth = height();
auto bubble = _parent->hasBubble();
@ -804,7 +807,7 @@ TextState Gif::textState(QPoint point, StateRequest request) const {
? _cancell
: _realParent->isSending()
? nullptr
: (_data->loaded() || _data->canBePlayed())
: (dataLoaded() || _dataMedia->canBePlayed())
? _openl
: _data->loading()
? _cancell
@ -871,13 +874,15 @@ void Gif::drawGrouped(
RectParts corners,
not_null<uint64*> cacheKey,
not_null<QPixmap*> cache) const {
ensureDataMediaCreated();
const auto item = _parent->data();
const auto loaded = dataLoaded();
const auto displayLoading = (item->id < 0) || _data->displayLoading();
const auto selected = (selection == FullSelection);
const auto autoPaused = App::wnd()->sessionController()->isGifPausedAtLeastFor(Window::GifPauseReason::Any);
const auto fullFeatured = fullFeaturedGrouped(sides);
const auto cornerDownload = fullFeatured && downloadInCorner();
const auto canBePlayed = _data->canBePlayed();
const auto canBePlayed = _dataMedia->canBePlayed();
const auto autoplay = fullFeatured
&& autoplayEnabled()
&& canBePlayed
@ -961,12 +966,12 @@ void Gif::drawGrouped(
if (radial
|| (!streamingMode
&& ((!_data->loaded() && !_data->loading()) || !autoplay))) {
&& ((!loaded && !_data->loading()) || !autoplay))) {
const auto radialOpacity = (item->isSending() || _data->uploading())
? 1.
: streamedForWaiting
? streamedForWaiting->waitingOpacity()
: (radial && _data->loaded())
: (radial && loaded)
? _animation->radial.opacity()
: 1.;
const auto radialSize = st::historyGroupRadialSize;
@ -998,7 +1003,7 @@ void Gif::drawGrouped(
return &(selected ? st::historyFileThumbWaitingSelected : st::historyFileThumbWaiting);
} else if (streamingMode && !_data->uploading()) {
return nullptr;
} else if ((_data->loaded() || canBePlayed) && (!radial || cornerDownload)) {
} else if ((loaded || canBePlayed) && (!radial || cornerDownload)) {
return &(selected ? st::historyFileThumbPlaySelected : st::historyFileThumbPlay);
} else if (radial || _data->loading()) {
if (!item->isSending() || _data->uploading()) {
@ -1064,11 +1069,12 @@ TextState Gif::getStateGrouped(
return state;
}
}
ensureDataMediaCreated();
return TextState(_parent, _data->uploading()
? _cancell
: _realParent->isSending()
? nullptr
: (_data->loaded() || _data->canBePlayed())
: (dataLoaded() || _dataMedia->canBePlayed())
? _openl
: _data->loading()
? _cancell
@ -1206,6 +1212,7 @@ void Gif::setStatusSize(int newSize) const {
}
void Gif::updateStatusText() const {
ensureDataMediaCreated();
auto showPause = false;
auto statusSize = 0;
auto realDuration = 0;
@ -1215,7 +1222,7 @@ void Gif::updateStatusText() const {
statusSize = _data->uploadingData->offset;
} else if (!downloadInCorner() && _data->loading()) {
statusSize = _data->loadOffset();
} else if (_data->loaded() || _data->canBePlayed()) {
} else if (dataLoaded() || _dataMedia->canBePlayed()) {
statusSize = FileStatusSizeLoaded;
} else {
statusSize = FileStatusSizeReady;
@ -1331,6 +1338,7 @@ Gif::Streamed *Gif::activeOwnStreamed() const {
}
void Gif::playAnimation(bool autoplay) {
ensureDataMediaCreated();
if (_data->isVideoMessage() && !autoplay) {
return;
} else if (_streamed && autoplay) {
@ -1342,7 +1350,7 @@ void Gif::playAnimation(bool autoplay) {
}
if (_streamed) {
stopAnimation();
} else if (_data->canBePlayed()) {
} else if (_dataMedia->canBePlayed()) {
if (!autoplayEnabled()) {
history()->owner().checkPlayingVideoFiles();
}
@ -1470,8 +1478,9 @@ int Gif::checkAnimationCount() {
}
float64 Gif::dataProgress() const {
ensureDataMediaCreated();
return (_data->uploading() || _parent->data()->id > 0)
? _data->progress()
? _dataMedia->progress()
: 0;
}
@ -1482,7 +1491,8 @@ bool Gif::dataFinished() const {
}
bool Gif::dataLoaded() const {
return (_parent->data()->id > 0) ? _data->loaded() : false;
ensureDataMediaCreated();
return (_parent->data()->id > 0) ? _dataMedia->loaded() : false;
}
bool Gif::needInfoDisplay() const {

View file

@ -102,7 +102,7 @@ bool Sticker::readyToDrawLottie() {
ensureDataMediaCreated();
_dataMedia->checkStickerLarge();
const auto loaded = _data->loaded();
const auto loaded = _dataMedia->loaded();
if (sticker->animated && !_lottie && loaded) {
setupLottie();
}

View file

@ -108,9 +108,11 @@ QSize ThemeDocument::countCurrentSize(int newWidth) {
void ThemeDocument::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
ensureDataMediaCreated();
_data->automaticLoad(_realParent->fullId(), _parent->data());
auto selected = (selection == FullSelection);
auto loaded = _data->loaded();
auto loaded = dataLoaded();
auto displayLoading = _data->displayLoading();
auto inWebPage = (_parent->media() != this);
@ -121,7 +123,7 @@ void ThemeDocument::draw(Painter &p, const QRect &r, TextSelection selection, cr
if (displayLoading) {
ensureAnimation();
if (!_animation->radial.animating()) {
_animation->radial.start(_data->progress());
_animation->radial.start(dataProgress());
}
}
const auto radial = isRadialAnimation();
@ -185,15 +187,20 @@ void ThemeDocument::draw(Painter &p, const QRect &r, TextSelection selection, cr
}
}
void ThemeDocument::ensureDataMediaCreated() const {
if (_dataMedia) {
return;
}
_dataMedia = _data->createMediaView();
_dataMedia->goodThumbnailWanted();
_parent->history()->owner().registerHeavyViewPart(_parent);
}
void ThemeDocument::validateThumbnail() const {
if (_thumbnailGood > 0) {
return;
}
if (!_dataMedia) {
_dataMedia = _data->createMediaView();
_dataMedia->goodThumbnailWanted();
_parent->history()->owner().registerHeavyViewPart(_parent);
}
ensureDataMediaCreated();
if (const auto good = _dataMedia->goodThumbnail()) {
if (good->loaded()) {
prepareThumbnailFrom(good, 1);
@ -261,7 +268,7 @@ TextState ThemeDocument::textState(QPoint point, StateRequest request) const {
if (QRect(paintx, painty, paintw, painth).contains(point)) {
if (_data->uploading()) {
result.link = _cancell;
} else if (_data->loaded()) {
} else if (dataLoaded()) {
result.link = _openl;
} else if (_data->loading()) {
result.link = _cancell;
@ -273,7 +280,8 @@ TextState ThemeDocument::textState(QPoint point, StateRequest request) const {
}
float64 ThemeDocument::dataProgress() const {
return _data->progress();
ensureDataMediaCreated();
return _dataMedia->progress();
}
bool ThemeDocument::dataFinished() const {
@ -282,11 +290,13 @@ bool ThemeDocument::dataFinished() const {
}
bool ThemeDocument::dataLoaded() const {
return _data->loaded();
ensureDataMediaCreated();
return _dataMedia->loaded();
}
bool ThemeDocument::isReadyForOpen() const {
return _data->loaded();
ensureDataMediaCreated();
return _dataMedia->loaded();
}
QString ThemeDocument::additionalInfoString() const {

View file

@ -61,6 +61,7 @@ private:
void fillPatternFieldsFrom(const QString &url);
void validateThumbnail() const;
void prepareThumbnailFrom(not_null<Image*> image, int good) const;
void ensureDataMediaCreated() const;
const not_null<DocumentData*> _data;
int _pixw = 1;

View file

@ -146,12 +146,10 @@ int Gif::resizeGetHeight(int width) {
void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) const {
const auto document = getShownDocument();
if (document) {
ensureDataMediaCreated(document);
}
ensureDataMediaCreated(document);
document->automaticLoad(fileOrigin(), nullptr);
bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading();
bool loaded = _dataMedia->loaded(), loading = document->loading(), displayLoading = document->displayLoading();
if (loaded
&& !_gif
&& !_gif.isBad()
@ -167,7 +165,7 @@ void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) cons
if (displayLoading) {
ensureAnimation();
if (!_animation->radial.animating()) {
_animation->radial.start(document->progress());
_animation->radial.start(_dataMedia->progress());
}
}
const auto radial = isRadialAnimation();
@ -260,7 +258,8 @@ void Gif::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
if (p == _delete || p == _send) {
bool wasactive = (_state & StateFlag::Over);
if (active != wasactive) {
if (!getShownDocument()->loaded()) {
ensureDataMediaCreated(getShownDocument());
if (!_dataMedia->loaded()) {
ensureAnimation();
auto from = active ? 0. : 1., to = active ? 1. : 0.;
_animation->_a_over.start([this] { update(); }, from, to, st::stickersRowDuration);
@ -356,8 +355,11 @@ bool Gif::isRadialAnimation() const {
if (_animation) {
if (_animation->radial.animating()) {
return true;
} else if (getShownDocument()->loaded()) {
_animation = nullptr;
} else {
ensureDataMediaCreated(getShownDocument());
if (_dataMedia->loaded()) {
_animation = nullptr;
}
}
}
return false;
@ -365,16 +367,17 @@ bool Gif::isRadialAnimation() const {
void Gif::radialAnimationCallback(crl::time now) const {
const auto document = getShownDocument();
ensureDataMediaCreated(document);
const auto updated = [&] {
return _animation->radial.update(
document->progress(),
!document->loading() || document->loaded(),
_dataMedia->progress(),
!document->loading() || _dataMedia->loaded(),
now);
}();
if (!anim::Disabled() || updated) {
update();
}
if (!_animation->radial.animating() && document->loaded()) {
if (!_animation->radial.animating() && _dataMedia->loaded()) {
_animation = nullptr;
}
}
@ -452,7 +455,8 @@ void Sticker::ensureDataMediaCreated(not_null<DocumentData*> document) const {
}
void Sticker::paint(Painter &p, const QRect &clip, const PaintContext *context) const {
bool loaded = getShownDocument()->loaded();
ensureDataMediaCreated(getShownDocument());
bool loaded = _dataMedia->loaded();
auto over = _a_over.value(_active ? 1. : 0.);
if (over > 0) {
@ -534,12 +538,12 @@ void Sticker::prepareThumbnail() const {
if (!_lottie
&& document->sticker()
&& document->sticker()->animated
&& document->loaded()) {
&& _dataMedia->loaded()) {
setupLottie();
}
_dataMedia->checkStickerSmall();
if (const auto sticker = _dataMedia->getStickerSmall()) {
if (!_lottie && !_thumbLoaded && sticker->loaded()) {
if (!_lottie && !_thumbLoaded && _dataMedia->loaded()) {
const auto thumbSize = getThumbSize();
_thumb = sticker->pix(
document->stickerSetOrigin(),
@ -831,12 +835,13 @@ void File::initDimensions() {
void File::paint(Painter &p, const QRect &clip, const PaintContext *context) const {
const auto left = st::msgFileSize + st::inlineThumbSkip;
const auto loaded = _document->loaded();
ensureDataMediaCreated();
const auto loaded = _documentMedia->loaded();
const auto displayLoading = _document->displayLoading();
if (displayLoading) {
ensureAnimation();
if (!_animation->radial.animating()) {
_animation->radial.start(_document->progress());
_animation->radial.start(_documentMedia->progress());
}
}
const auto showPause = updateStatusText();
@ -862,21 +867,18 @@ void File::paint(Painter &p, const QRect &clip, const PaintContext *context) con
_animation->radial.draw(p, radialCircle, st::msgFileRadialLine, st::historyFileInRadialFg);
}
auto icon = [&] {
const auto icon = [&] {
if (radial || _document->loading()) {
return &st::historyFileInCancel;
} else if (showPause) {
return &st::historyFileInPause;
} else if (true || _document->loaded()) {
if (_document->isImage()) {
return &st::historyFileInImage;
} else if (_document->isVoiceMessage()
|| _document->isAudioFile()) {
return &st::historyFileInPlay;
}
return &st::historyFileInDocument;
} else if (_document->isImage()) {
return &st::historyFileInImage;
} else if (_document->isVoiceMessage()
|| _document->isAudioFile()) {
return &st::historyFileInPlay;
}
return &st::historyFileInDownload;
return &st::historyFileInDocument;
}();
icon->paintInCenter(p, inner);
@ -934,10 +936,11 @@ void File::thumbAnimationCallback() {
}
void File::radialAnimationCallback(crl::time now) const {
ensureDataMediaCreated();
const auto updated = [&] {
return _animation->radial.update(
_document->progress(),
!_document->loading() || _document->loaded(),
_documentMedia->progress(),
!_document->loading() || _documentMedia->loaded(),
now);
}();
if (!anim::Disabled() || updated) {
@ -956,17 +959,26 @@ void File::ensureAnimation() const {
}
}
void File::ensureDataMediaCreated() const {
if (_documentMedia) {
return;
}
_documentMedia = _document->createMediaView();
}
void File::checkAnimationFinished() const {
if (_animation
&& !_animation->a_thumbOver.animating()
&& !_animation->radial.animating()) {
if (_document->loaded()) {
ensureDataMediaCreated();
if (_documentMedia->loaded()) {
_animation.reset();
}
}
}
bool File::updateStatusText() const {
ensureDataMediaCreated();
bool showPause = false;
int32 statusSize = 0, realDuration = 0;
if (_document->status == FileDownloadFailed || _document->status == FileUploadFailed) {
@ -975,7 +987,7 @@ bool File::updateStatusText() const {
statusSize = _document->uploadingData->offset;
} else if (_document->loading()) {
statusSize = _document->loadOffset();
} else if (_document->loaded()) {
} else if (_documentMedia->loaded()) {
statusSize = FileStatusSizeLoaded;
} else {
statusSize = FileStatusSizeReady;
@ -1331,7 +1343,7 @@ void Game::paint(Painter &p, const QRect &clip, const PaintContext *context) con
if (animatedThumb) {
document->automaticLoad(fileOrigin(), nullptr);
bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading();
bool loaded = _dataMedia->loaded(), loading = document->loading(), displayLoading = document->displayLoading();
if (loaded && !_gif && !_gif.isBad()) {
auto that = const_cast<Game*>(this);
that->_gif = Media::Clip::MakeReader(_dataMedia.get(), FullMsgId(), [that](Media::Clip::Notification notification) {
@ -1348,7 +1360,7 @@ void Game::paint(Painter &p, const QRect &clip, const PaintContext *context) con
});
}
if (!_radial->animating()) {
_radial->start(document->progress());
_radial->start(_dataMedia->progress());
}
}
radial = isRadialAnimation();
@ -1466,8 +1478,11 @@ bool Game::isRadialAnimation() const {
if (_radial) {
if (_radial->animating()) {
return true;
} else if (getResultDocument()->loaded()) {
_radial = nullptr;
} else {
ensureDataMediaCreated(getResultDocument());
if (_dataMedia->loaded()) {
_radial = nullptr;
}
}
}
return false;
@ -1475,16 +1490,17 @@ bool Game::isRadialAnimation() const {
void Game::radialAnimationCallback(crl::time now) const {
const auto document = getResultDocument();
ensureDataMediaCreated(document);
const auto updated = [&] {
return _radial->update(
document->progress(),
!document->loading() || document->loaded(),
_dataMedia->progress(),
!document->loading() || _dataMedia->loaded(),
now);
}();
if (!anim::Disabled() || updated) {
update();
}
if (!_radial->animating() && document->loaded()) {
if (!_radial->animating() && _dataMedia->loaded()) {
_radial = nullptr;
}
}

View file

@ -279,6 +279,7 @@ private:
void radialAnimationCallback(crl::time now) const;
void ensureAnimation() const;
void ensureDataMediaCreated() const;
void checkAnimationFinished() const;
bool updateStatusText() const;
@ -326,6 +327,7 @@ private:
void setStatusSize(int32 newSize, int32 fullSize, int32 duration, qint64 realDuration) const;
not_null<DocumentData*> _document;
mutable std::shared_ptr<Data::DocumentMedia> _documentMedia;
};

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h"
#include "data/data_peer.h"
#include "data/data_file_origin.h"
#include "data/data_document_media.h"
#include "core/click_handler_types.h"
#include "inline_bots/inline_bot_result.h"
#include "inline_bots/inline_bot_layout_internal.h"
@ -48,19 +49,10 @@ PhotoData *ItemBase::getPhoto() const {
}
DocumentData *ItemBase::getPreviewDocument() const {
auto previewDocument = [this]() -> DocumentData* {
if (_doc) {
return _doc;
}
if (_result) {
return _result->_document;
}
return nullptr;
};
if (DocumentData *result = previewDocument()) {
if (result->sticker() || result->loaded()) {
return result;
}
if (_doc) {
return _doc;
} else if (_result) {
return _result->_document;
}
return nullptr;
}
@ -193,7 +185,8 @@ ClickHandlerPtr ItemBase::getResultPreviewHandler() const {
return std::make_shared<UrlClickHandler>(
_result->_content_url,
false);
} else if (_result->_document && _result->_document->canBePlayed()) {
} else if (_result->_document
&& _result->_document->createMediaView()->canBePlayed()) { // #TODO optimize
return std::make_shared<DocumentOpenClickHandler>(
_result->_document);
} else if (_result->_photo) {

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h"
#include "data/data_session.h"
#include "data/data_file_origin.h"
#include "data/data_document_media.h"
#include "inline_bots/inline_bot_layout_item.h"
#include "inline_bots/inline_bot_send_data.h"
#include "storage/file_download.h"
@ -268,7 +269,8 @@ bool Result::onChoose(Layout::ItemBase *layout) {
_type == Type::File ||
_type == Type::Gif)) {
if (_type == Type::Gif) {
if (_document->loaded()) {
const auto media = _document->activeMediaView();
if (!media || media->loaded()) {
return true;
} else if (_document->loading()) {
_document->cancel();

View file

@ -723,11 +723,9 @@ void Inner::showPreview() {
auto layout = _rows.at(row).items.at(col);
if (const auto w = App::wnd()) {
if (const auto previewDocument = layout->getPreviewDocument()) {
w->showMediaPreview(Data::FileOrigin(), previewDocument);
_previewShown = true;
_previewShown = w->showMediaPreview(Data::FileOrigin(), previewDocument);
} else if (const auto previewPhoto = layout->getPreviewPhoto()) {
w->showMediaPreview(Data::FileOrigin(), previewPhoto);
_previewShown = true;
_previewShown = w->showMediaPreview(Data::FileOrigin(), previewPhoto);
}
}
}

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <rpl/flatten_latest.h>
#include "data/data_photo.h"
#include "data/data_document.h"
#include "data/data_document_media.h"
#include "data/data_web_page.h"
#include "data/data_game.h"
#include "data/data_peer_values.h"
@ -365,6 +366,7 @@ struct MainWidget::SettingBackground {
explicit SettingBackground(const Data::WallPaper &data);
Data::WallPaper data;
std::shared_ptr<Data::DocumentMedia> dataMedia;
base::binary_guard generating;
};
@ -1326,6 +1328,9 @@ void MainWidget::setChatBackground(
}
_background = std::make_unique<SettingBackground>(background);
if (const auto document = _background->data.document()) {
_background->dataMedia = document->createMediaView();
}
_background->data.loadDocument();
checkChatBackground();
@ -1375,7 +1380,7 @@ float64 MainWidget::chatBackgroundProgress() const {
if (_background->generating) {
return 1.;
} else if (const auto document = _background->data.document()) {
return document->progress();
return _background->dataMedia->progress();
} else if (const auto thumbnail = _background->data.thumbnail()) {
return thumbnail->progress();
}
@ -1387,12 +1392,15 @@ void MainWidget::checkChatBackground() {
if (!_background || _background->generating) {
return;
}
const auto document = _background->data.document();
Assert(document != nullptr);
if (!document->loaded()) {
const auto &media = _background->dataMedia;
Assert(media != nullptr);
if (!media->loaded()) {
return;
}
const auto document = _background->data.document();
Assert(document != nullptr);
const auto generateCallback = [=](QImage &&image) {
const auto background = base::take(_background);
const auto ready = image.isNull()
@ -1401,7 +1409,7 @@ void MainWidget::checkChatBackground() {
setReadyChatBackground(ready, std::move(image));
};
_background->generating = Data::ReadImageAsync(
document,
media.get(),
Window::Theme::ProcessBackgroundImage,
generateCallback);
}

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h"
#include "data/data_session.h"
#include "data/data_document_media.h"
#include "dialogs/dialogs_layout.h"
#include "history/history.h"
#include "ui/widgets/popup_menu.h"
@ -429,11 +430,13 @@ bool MainWindow::ui_isLayerShown() {
return _layer != nullptr;
}
void MainWindow::showMediaPreview(
bool MainWindow::showMediaPreview(
Data::FileOrigin origin,
not_null<DocumentData*> document) {
if (!document || ((!document->isAnimation() || !document->loaded()) && !document->sticker())) {
return;
const auto media = document->activeMediaView();
if (!document->sticker()
&& (!document->isAnimation() || !media || !media->loaded())) {
return false;
}
if (!_mediaPreview) {
_mediaPreview.create(bodyWidget(), sessionController());
@ -443,14 +446,12 @@ void MainWindow::showMediaPreview(
fixOrder();
}
_mediaPreview->showPreview(origin, document);
return true;
}
void MainWindow::showMediaPreview(
bool MainWindow::showMediaPreview(
Data::FileOrigin origin,
not_null<PhotoData*> photo) {
if (!photo) {
return;
}
if (!_mediaPreview) {
_mediaPreview.create(bodyWidget(), sessionController());
updateControlsGeometry();
@ -459,6 +460,7 @@ void MainWindow::showMediaPreview(
fixOrder();
}
_mediaPreview->showPreview(origin, photo);
return true;
}
void MainWindow::hideMediaPreview() {

View file

@ -110,10 +110,10 @@ public:
void ui_hideSettingsAndLayer(anim::type animated);
void ui_removeLayerBlackout();
bool ui_isLayerShown();
void showMediaPreview(
bool showMediaPreview(
Data::FileOrigin origin,
not_null<DocumentData*> document);
void showMediaPreview(
bool showMediaPreview(
Data::FileOrigin origin,
not_null<PhotoData*> photo);
void hideMediaPreview();

View file

@ -927,7 +927,7 @@ void OverlayWidget::resizeContentByScreenSize() {
float64 OverlayWidget::radialProgress() const {
if (_doc) {
return _doc->progress();
return _docMedia->progress();
} else if (_photo) {
return _photo->large()->progress();
}
@ -983,7 +983,7 @@ bool OverlayWidget::radialAnimationCallback(crl::time now) {
update(radialRect());
}
const auto ready = _doc && _docMedia->loaded();
const auto streamVideo = ready && _doc->canBePlayed();
const auto streamVideo = ready && _docMedia->canBePlayed();
const auto tryOpenImage = ready && (_doc->size < App::kImageSizeLimit);
if (ready && ((tryOpenImage && !_radial.animating()) || streamVideo)) {
_streamingStartPaused = false;
@ -1296,7 +1296,7 @@ void OverlayWidget::onDocClick() {
_doc,
Auth().data().message(_msgid));
if (_doc->loading() && !_radial.animating()) {
_radial.start(_doc->progress());
_radial.start(_docMedia->progress());
}
}
}
@ -1371,7 +1371,7 @@ void OverlayWidget::onDownload() {
void OverlayWidget::onSaveCancel() {
if (_doc && _doc->loading()) {
_doc->cancel();
if (_doc->canBePlayed()) {
if (_docMedia->canBePlayed()) {
redisplayContent();
}
}
@ -1997,7 +1997,8 @@ void OverlayWidget::displayDocument(
_doc->dimensions.height());
}
} else {
if (_doc->canBePlayed() && initStreaming(continueStreaming)) {
if (_docMedia->canBePlayed()
&& initStreaming(continueStreaming)) {
} else if (_doc->isVideoFile()) {
_doc->automaticLoad(fileOrigin(), item);
initStreamingThumbnail();
@ -2132,7 +2133,7 @@ void OverlayWidget::displayFinished() {
bool OverlayWidget::initStreaming(bool continueStreaming) {
Expects(_doc != nullptr);
Expects(_doc->canBePlayed());
Expects(_docMedia->canBePlayed());
if (_streamed) {
return true;
@ -2316,12 +2317,14 @@ void OverlayWidget::handleStreamingUpdate(Streaming::Update &&update) {
}
void OverlayWidget::handleStreamingError(Streaming::Error &&error) {
Expects(_doc != nullptr);
if (error == Streaming::Error::NotStreamable) {
_doc->setNotSupportsStreaming();
} else if (error == Streaming::Error::OpenFailed) {
_doc->setInappPlaybackFailed();
}
if (!_doc->canBePlayed()) {
if (!_docMedia->canBePlayed()) {
redisplayContent();
} else {
updatePlaybackState();
@ -2490,7 +2493,7 @@ void OverlayWidget::playbackPauseResume() {
_streamed->resumeOnCallEnd = false;
if (_streamed->instance.player().failed()) {
clearStreaming();
if (!_doc->canBePlayed() || !initStreaming()) {
if (!_docMedia->canBePlayed() || !initStreaming()) {
redisplayContent();
}
} else if (_streamed->instance.player().finished()
@ -3489,11 +3492,12 @@ void OverlayWidget::preloadData(int delta) {
auto entity = entityByIndex(index);
if (auto photo = base::get_if<not_null<PhotoData*>>(&entity.data)) {
(*photo)->download(fileOrigin());
} else if (auto document = base::get_if<not_null<DocumentData*>>(&entity.data)) {
} else if (auto document = base::get_if<not_null<DocumentData*>>(
&entity.data)) {
(*document)->loadThumbnail(fileOrigin());
if (!(*document)->canBePlayed()) {
(*document)->automaticLoad(fileOrigin(), entity.item);
}
//if (!(*document)->canBePlayed()) { // #TODO optimize
// (*document)->automaticLoad(fileOrigin(), entity.item);
//}
}
}
}

View file

@ -447,7 +447,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
if (displayLoading) {
ensureRadial();
if (!_radial->animating()) {
_radial->start(_data->progress());
_radial->start(dataProgress());
}
}
updateStatusText();
@ -490,7 +490,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
if (!selected && !context->selecting && radialOpacity < 1.) {
if (clip.intersects(QRect(0, _height - st::normalFont->height, _width, st::normalFont->height))) {
const auto download = !loaded && !_data->canBePlayed();
const auto download = !loaded && !_dataMedia->canBePlayed();
const auto &icon = download
? (selected ? st::overviewVideoDownloadSelected : st::overviewVideoDownload)
: (selected ? st::overviewVideoPlaySelected : st::overviewVideoPlay);
@ -516,7 +516,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
if (selected) {
p.setBrush(st::msgDateImgBgSelected);
} else {
auto over = ClickHandler::showAsActive((_data->loading() || _data->uploading()) ? _cancell : (loaded || _data->canBePlayed()) ? _openl : _savel);
auto over = ClickHandler::showAsActive((_data->loading() || _data->uploading()) ? _cancell : (loaded || _dataMedia->canBePlayed()) ? _openl : _savel);
p.setBrush(anim::brush(st::msgDateImgBg, st::msgDateImgBgOver, _a_iconOver.value(over ? 1. : 0.)));
}
@ -552,7 +552,8 @@ void Video::ensureDataMediaCreated() const {
}
float64 Video::dataProgress() const {
return _data->progress();
ensureDataMediaCreated();
return _dataMedia->progress();
}
bool Video::dataFinished() const {
@ -560,7 +561,8 @@ bool Video::dataFinished() const {
}
bool Video::dataLoaded() const {
return _dataMedia ? _dataMedia->loaded() : !_data->filepath().isEmpty();
ensureDataMediaCreated();
return _dataMedia->loaded();
}
bool Video::iconAnimated() const {
@ -571,9 +573,10 @@ TextState Video::getState(
QPoint point,
StateRequest request) const {
if (hasPoint(point)) {
ensureDataMediaCreated();
const auto link = (_data->loading() || _data->uploading())
? _cancell
: (dataLoaded() || _data->canBePlayed())
: (dataLoaded() || _dataMedia->canBePlayed())
? _openl
: _savel;
return { parent(), link };
@ -641,13 +644,14 @@ void Voice::initDimensions() {
}
void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
ensureDataMediaCreated();
bool selected = (selection == FullSelection);
bool loaded = dataLoaded(), displayLoading = _data->displayLoading();
if (displayLoading) {
ensureRadial();
if (!_radial->animating()) {
_radial->start(_data->progress());
_radial->start(dataProgress());
}
}
const auto showPause = updateStatusText();
@ -699,7 +703,7 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
}
const auto &checkLink = (_data->loading() || _data->uploading())
? _cancell
: (_data->canBePlayed() || loaded)
: (_dataMedia->canBePlayed() || loaded)
? _openl
: _savel;
if (selected) {
@ -727,7 +731,7 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
return &(selected ? _st.songCancelSelected : _st.songCancel);
} else if (showPause) {
return &(selected ? _st.songPauseSelected : _st.songPause);
} else if (_data->canBePlayed()) {
} else if (_dataMedia->canBePlayed()) {
return &(selected ? _st.songPlaySelected : _st.songPlay);
}
return &(selected ? _st.songDownloadSelected : _st.songDownload);
@ -776,6 +780,7 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
TextState Voice::getState(
QPoint point,
StateRequest request) const {
ensureDataMediaCreated();
const auto loaded = dataLoaded();
const auto nameleft = _st.songPadding.left()
@ -794,7 +799,7 @@ TextState Voice::getState(
if (inner.contains(point)) {
const auto link = (_data->loading() || _data->uploading())
? _cancell
: (_data->canBePlayed() || loaded)
: (_dataMedia->canBePlayed() || loaded)
? _openl
: _savel;
return { parent(), link };
@ -839,7 +844,8 @@ void Voice::ensureDataMediaCreated() const {
}
float64 Voice::dataProgress() const {
return _data->progress();
ensureDataMediaCreated();
return _dataMedia->progress();
}
bool Voice::dataFinished() const {
@ -847,7 +853,8 @@ bool Voice::dataFinished() const {
}
bool Voice::dataLoaded() const {
return _dataMedia ? _dataMedia->loaded() : !_data->filepath().isEmpty();
ensureDataMediaCreated();
return _dataMedia->loaded();
}
bool Voice::iconAnimated() const {
@ -959,6 +966,8 @@ void Document::initDimensions() {
}
void Document::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
ensureDataMediaCreated();
const auto selected = (selection == FullSelection);
const auto cornerDownload = downloadInCorner();
@ -970,7 +979,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
if (displayLoading) {
ensureRadial();
if (!_radial->animating()) {
_radial->start(_data->progress());
_radial->start(dataProgress());
}
}
const auto showPause = updateStatusText();
@ -992,7 +1001,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
if (selected) {
p.setBrush(st::msgFileInBgSelected);
} else {
auto over = ClickHandler::showAsActive((!cornerDownload && (_data->loading() || _data->uploading())) ? _cancell : (loaded || _data->canBePlayed()) ? _openl : _savel);
auto over = ClickHandler::showAsActive((!cornerDownload && (_data->loading() || _data->uploading())) ? _cancell : (loaded || _dataMedia->canBePlayed()) ? _openl : _savel);
p.setBrush(anim::brush(_st.songIconBg, _st.songOverBg, _a_iconOver.value(over ? 1. : 0.)));
}
@ -1006,7 +1015,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
return &(selected ? _st.songCancelSelected : _st.songCancel);
} else if (showPause) {
return &(selected ? _st.songPauseSelected : _st.songPause);
} else if (loaded || _data->canBePlayed()) {
} else if (loaded || _dataMedia->canBePlayed()) {
return &(selected ? _st.songPlaySelected : _st.songPlay);
}
return &(selected ? _st.songDownloadSelected : _st.songDownload);
@ -1187,6 +1196,7 @@ TextState Document::cornerDownloadTextState(
TextState Document::getState(
QPoint point,
StateRequest request) const {
ensureDataMediaCreated();
const auto loaded = dataLoaded();
const auto wthumb = withThumb();
@ -1213,7 +1223,7 @@ TextState Document::getState(
const auto link = (!downloadInCorner()
&& (_data->loading() || _data->uploading()))
? _cancell
: (loaded || _data->canBePlayed())
: (loaded || _dataMedia->canBePlayed())
? _openl
: _savel;
return { parent(), link };
@ -1300,7 +1310,8 @@ void Document::ensureDataMediaCreated() const {
}
float64 Document::dataProgress() const {
return _data->progress();
ensureDataMediaCreated();
return _dataMedia->progress();
}
bool Document::dataFinished() const {
@ -1308,7 +1319,8 @@ bool Document::dataFinished() const {
}
bool Document::dataLoaded() const {
return _dataMedia ? _dataMedia->loaded() : !_data->filepath().isEmpty();
ensureDataMediaCreated();
return _dataMedia->loaded();
}
bool Document::iconAnimated() const {