mirror of https://github.com/procxx/kepka.git
Fix sending of thumbnailed inline result GIFs.
This commit is contained in:
parent
3c9ca2eb94
commit
c61f3a0aba
|
@ -453,6 +453,7 @@ DocumentData::DocumentData(not_null<Data::Session*> owner, DocumentId id)
|
||||||
|
|
||||||
DocumentData::~DocumentData() {
|
DocumentData::~DocumentData() {
|
||||||
base::take(_thumbnailLoader).reset();
|
base::take(_thumbnailLoader).reset();
|
||||||
|
base::take(_videoThumbnailLoader).reset();
|
||||||
destroyLoader();
|
destroyLoader();
|
||||||
unload();
|
unload();
|
||||||
}
|
}
|
||||||
|
@ -672,7 +673,9 @@ bool DocumentData::thumbnailFailed() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentData::loadThumbnail(Data::FileOrigin origin) {
|
void DocumentData::loadThumbnail(Data::FileOrigin origin) {
|
||||||
if (_thumbnailLoader || (_flags & Flag::ThumbnailFailed)) {
|
if (_thumbnailLoader
|
||||||
|
|| (_flags & Flag::ThumbnailFailed)
|
||||||
|
|| !_thumbnailLocation.valid()) {
|
||||||
return;
|
return;
|
||||||
} else if (const auto active = activeMediaView()) {
|
} else if (const auto active = activeMediaView()) {
|
||||||
if (active->thumbnail()) {
|
if (active->thumbnail()) {
|
||||||
|
@ -728,7 +731,9 @@ bool DocumentData::videoThumbnailFailed() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentData::loadVideoThumbnail(Data::FileOrigin origin) {
|
void DocumentData::loadVideoThumbnail(Data::FileOrigin origin) {
|
||||||
if (_videoThumbnailLoader || (_flags & Flag::VideoThumbnailFailed)) {
|
if (_videoThumbnailLoader
|
||||||
|
|| (_flags & Flag::VideoThumbnailFailed)
|
||||||
|
|| !_videoThumbnailLocation.valid()) {
|
||||||
return;
|
return;
|
||||||
} else if (const auto active = activeMediaView()) {
|
} else if (const auto active = activeMediaView()) {
|
||||||
if (!active->videoThumbnailContent().isEmpty()) {
|
if (!active->videoThumbnailContent().isEmpty()) {
|
||||||
|
|
|
@ -85,6 +85,56 @@ enum class FileType {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
VideoPreviewState::VideoPreviewState(DocumentMedia *media)
|
||||||
|
: _media(media)
|
||||||
|
, _usingThumbnail(media ? media->owner()->hasVideoThumbnail() : false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoPreviewState::automaticLoad(Data::FileOrigin origin) const {
|
||||||
|
Expects(_media != nullptr);
|
||||||
|
|
||||||
|
if (_usingThumbnail) {
|
||||||
|
_media->videoThumbnailWanted(origin);
|
||||||
|
} else {
|
||||||
|
_media->automaticLoad(origin, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::Media::Clip::ReaderPointer VideoPreviewState::makeAnimation(
|
||||||
|
Fn<void(::Media::Clip::Notification)> callback) const {
|
||||||
|
Expects(_media != nullptr);
|
||||||
|
Expects(loaded());
|
||||||
|
|
||||||
|
return _usingThumbnail
|
||||||
|
? ::Media::Clip::MakeReader(
|
||||||
|
_media->videoThumbnailContent(),
|
||||||
|
std::move(callback))
|
||||||
|
: ::Media::Clip::MakeReader(
|
||||||
|
_media,
|
||||||
|
FullMsgId(),
|
||||||
|
std::move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoPreviewState::usingThumbnail() const {
|
||||||
|
return _usingThumbnail;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoPreviewState::loading() const {
|
||||||
|
return _usingThumbnail
|
||||||
|
? _media->owner()->videoThumbnailLoading()
|
||||||
|
: _media
|
||||||
|
? _media->owner()->loading()
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoPreviewState::loaded() const {
|
||||||
|
return _usingThumbnail
|
||||||
|
? !_media->videoThumbnailContent().isEmpty()
|
||||||
|
: _media
|
||||||
|
? _media->loaded()
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
DocumentMedia::DocumentMedia(not_null<DocumentData*> owner)
|
DocumentMedia::DocumentMedia(not_null<DocumentData*> owner)
|
||||||
: _owner(owner) {
|
: _owner(owner) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,34 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
class FileLoader;
|
class FileLoader;
|
||||||
|
|
||||||
|
namespace Media {
|
||||||
|
namespace Clip {
|
||||||
|
enum Notification : int;
|
||||||
|
class ReaderPointer;
|
||||||
|
} // namespace Clip
|
||||||
|
} // namespace Media
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
|
class DocumentMedia;
|
||||||
|
|
||||||
|
class VideoPreviewState final {
|
||||||
|
public:
|
||||||
|
explicit VideoPreviewState(DocumentMedia *media);
|
||||||
|
|
||||||
|
void automaticLoad(Data::FileOrigin origin) const;
|
||||||
|
[[nodiscard]] ::Media::Clip::ReaderPointer makeAnimation(
|
||||||
|
Fn<void(::Media::Clip::Notification)> callback) const;
|
||||||
|
[[nodiscard]] bool usingThumbnail() const;
|
||||||
|
[[nodiscard]] bool loading() const;
|
||||||
|
[[nodiscard]] bool loaded() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DocumentMedia *_media = nullptr;
|
||||||
|
bool _usingThumbnail = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class DocumentMedia final {
|
class DocumentMedia final {
|
||||||
public:
|
public:
|
||||||
explicit DocumentMedia(not_null<DocumentData*> owner);
|
explicit DocumentMedia(not_null<DocumentData*> owner);
|
||||||
|
|
|
@ -134,41 +134,28 @@ int Gif::resizeGetHeight(int width) {
|
||||||
void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) const {
|
void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) const {
|
||||||
const auto document = getShownDocument();
|
const auto document = getShownDocument();
|
||||||
const auto displayLoading = document->displayLoading();
|
const auto displayLoading = document->displayLoading();
|
||||||
const auto useVideoThumbnail = document->hasVideoThumbnail();
|
|
||||||
ensureDataMediaCreated(document);
|
ensureDataMediaCreated(document);
|
||||||
if (!useVideoThumbnail) {
|
const auto preview = Data::VideoPreviewState(_dataMedia.get());
|
||||||
_dataMedia->automaticLoad(fileOrigin(), nullptr);
|
preview.automaticLoad(fileOrigin());
|
||||||
}
|
|
||||||
|
|
||||||
const auto loaded = useVideoThumbnail
|
const auto loaded = preview.loaded();
|
||||||
? !_dataMedia->videoThumbnailContent().isEmpty()
|
const auto loading = preview.loading();
|
||||||
: _dataMedia->loaded();
|
|
||||||
const auto loading = useVideoThumbnail
|
|
||||||
? document->videoThumbnailLoading()
|
|
||||||
: document->loading();
|
|
||||||
if (loaded
|
if (loaded
|
||||||
&& !_gif
|
&& !_gif
|
||||||
&& !_gif.isBad()
|
&& !_gif.isBad()
|
||||||
&& CanPlayInline(document)) {
|
&& CanPlayInline(document)) {
|
||||||
auto that = const_cast<Gif*>(this);
|
auto that = const_cast<Gif*>(this);
|
||||||
const auto callback = [=](Media::Clip::Notification notification) {
|
that->_gif = preview.makeAnimation([=](
|
||||||
|
Media::Clip::Notification notification) {
|
||||||
that->clipCallback(notification);
|
that->clipCallback(notification);
|
||||||
};
|
});
|
||||||
that->_gif = useVideoThumbnail
|
|
||||||
? Media::Clip::MakeReader(
|
|
||||||
_dataMedia->videoThumbnailContent(),
|
|
||||||
callback)
|
|
||||||
: Media::Clip::MakeReader(
|
|
||||||
_dataMedia.get(),
|
|
||||||
FullMsgId(),
|
|
||||||
callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto animating = (_gif && _gif->started());
|
const auto animating = (_gif && _gif->started());
|
||||||
if (displayLoading) {
|
if (displayLoading) {
|
||||||
ensureAnimation();
|
ensureAnimation();
|
||||||
if (!_animation->radial.animating()) {
|
if (!_animation->radial.animating()) {
|
||||||
_animation->radial.start(_dataMedia->progress()); // #TODO video_thumbs
|
_animation->radial.start(_dataMedia->progress());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto radial = isRadialAnimation();
|
const auto radial = isRadialAnimation();
|
||||||
|
@ -192,12 +179,15 @@ void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) cons
|
||||||
p.drawPixmap(r.topLeft(), _thumb);
|
p.drawPixmap(r.topLeft(), _thumb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (useVideoThumbnail) {
|
|
||||||
AssertIsDebug();
|
AssertIsDebug();
|
||||||
|
if (preview.usingThumbnail()) {
|
||||||
p.fillRect(QRect(r.topLeft(), QSize(20, 20)), Qt::green);
|
p.fillRect(QRect(r.topLeft(), QSize(20, 20)), Qt::green);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radial || _gif.isBad() || (!_gif && !loaded && !loading)) {
|
if (radial
|
||||||
|
|| _gif.isBad()
|
||||||
|
|| (!_gif && !loaded && !loading && !preview.usingThumbnail())) {
|
||||||
auto radialOpacity = (radial && loaded) ? _animation->radial.opacity() : 1.;
|
auto radialOpacity = (radial && loaded) ? _animation->radial.opacity() : 1.;
|
||||||
if (_animation && _animation->_a_over.animating()) {
|
if (_animation && _animation->_a_over.animating()) {
|
||||||
auto over = _animation->_a_over.value(1.);
|
auto over = _animation->_a_over.value(1.);
|
||||||
|
@ -269,10 +259,11 @@ void Gif::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
||||||
bool wasactive = (_state & StateFlag::Over);
|
bool wasactive = (_state & StateFlag::Over);
|
||||||
if (active != wasactive) {
|
if (active != wasactive) {
|
||||||
ensureDataMediaCreated(getShownDocument());
|
ensureDataMediaCreated(getShownDocument());
|
||||||
if (!_dataMedia->loaded()) { // #TODO video_thumbs
|
const auto preview = Data::VideoPreviewState(_dataMedia.get());
|
||||||
|
if (!preview.usingThumbnail() && !preview.loaded()) {
|
||||||
ensureAnimation();
|
ensureAnimation();
|
||||||
auto from = active ? 0. : 1., to = active ? 1. : 0.;
|
auto from = active ? 0. : 1., to = active ? 1. : 0.;
|
||||||
_animation->_a_over.start([this] { update(); }, from, to, st::stickersRowDuration);
|
_animation->_a_over.start([=] { update(); }, from, to, st::stickersRowDuration);
|
||||||
}
|
}
|
||||||
if (active) {
|
if (active) {
|
||||||
_state |= StateFlag::Over;
|
_state |= StateFlag::Over;
|
||||||
|
@ -369,7 +360,8 @@ bool Gif::isRadialAnimation() const {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
ensureDataMediaCreated(getShownDocument());
|
ensureDataMediaCreated(getShownDocument());
|
||||||
if (_dataMedia->loaded()) { // #TODO video_thumbs
|
const auto preview = Data::VideoPreviewState(_dataMedia.get());
|
||||||
|
if (preview.usingThumbnail() || preview.loaded()) {
|
||||||
_animation = nullptr;
|
_animation = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,7 +374,7 @@ void Gif::radialAnimationCallback(crl::time now) const {
|
||||||
ensureDataMediaCreated(document);
|
ensureDataMediaCreated(document);
|
||||||
const auto updated = [&] {
|
const auto updated = [&] {
|
||||||
return _animation->radial.update(
|
return _animation->radial.update(
|
||||||
_dataMedia->progress(), // #TODO video_thumbs
|
_dataMedia->progress(),
|
||||||
!document->loading() || _dataMedia->loaded(),
|
!document->loading() || _dataMedia->loaded(),
|
||||||
now);
|
now);
|
||||||
}();
|
}();
|
||||||
|
|
|
@ -275,14 +275,17 @@ bool Result::onChoose(Layout::ItemBase *layout) {
|
||||||
_type == Type::Gif)) {
|
_type == Type::Gif)) {
|
||||||
if (_type == Type::Gif) {
|
if (_type == Type::Gif) {
|
||||||
const auto media = _document->activeMediaView();
|
const auto media = _document->activeMediaView();
|
||||||
if (!media || media->loaded()) {
|
const auto preview = Data::VideoPreviewState(media.get());
|
||||||
|
if (!media || preview.loaded()) {
|
||||||
return true;
|
return true;
|
||||||
} else if (_document->loading()) {
|
} else if (!preview.usingThumbnail()) {
|
||||||
_document->cancel();
|
if (preview.loading()) {
|
||||||
} else {
|
_document->cancel();
|
||||||
DocumentSaveClickHandler::Save(
|
} else {
|
||||||
Data::FileOriginSavedGifs(),
|
DocumentSaveClickHandler::Save(
|
||||||
_document);
|
Data::FileOriginSavedGifs(),
|
||||||
|
_document);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,13 +40,13 @@ struct FrameRequest {
|
||||||
RectParts corners = RectPart::AllCorners;
|
RectParts corners = RectPart::AllCorners;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ReaderSteps {
|
enum ReaderSteps : int {
|
||||||
WaitingForDimensionsStep = -3, // before ReaderPrivate read the first image and got the original frame size
|
WaitingForDimensionsStep = -3, // before ReaderPrivate read the first image and got the original frame size
|
||||||
WaitingForRequestStep = -2, // before Reader got the original frame size and prepared the frame request
|
WaitingForRequestStep = -2, // before Reader got the original frame size and prepared the frame request
|
||||||
WaitingForFirstFrameStep = -1, // before ReaderPrivate got the frame request and started waiting for the 1-2 delay
|
WaitingForFirstFrameStep = -1, // before ReaderPrivate got the frame request and started waiting for the 1-2 delay
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Notification {
|
enum Notification : int {
|
||||||
NotificationReinit,
|
NotificationReinit,
|
||||||
NotificationRepaint,
|
NotificationRepaint,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue