mirror of https://github.com/procxx/kepka.git
Fix sending of thumbnailed inline result GIFs.
This commit is contained in:
parent
3c9ca2eb94
commit
c61f3a0aba
Telegram/SourceFiles
|
@ -453,6 +453,7 @@ DocumentData::DocumentData(not_null<Data::Session*> owner, DocumentId id)
|
|||
|
||||
DocumentData::~DocumentData() {
|
||||
base::take(_thumbnailLoader).reset();
|
||||
base::take(_videoThumbnailLoader).reset();
|
||||
destroyLoader();
|
||||
unload();
|
||||
}
|
||||
|
@ -672,7 +673,9 @@ bool DocumentData::thumbnailFailed() const {
|
|||
}
|
||||
|
||||
void DocumentData::loadThumbnail(Data::FileOrigin origin) {
|
||||
if (_thumbnailLoader || (_flags & Flag::ThumbnailFailed)) {
|
||||
if (_thumbnailLoader
|
||||
|| (_flags & Flag::ThumbnailFailed)
|
||||
|| !_thumbnailLocation.valid()) {
|
||||
return;
|
||||
} else if (const auto active = activeMediaView()) {
|
||||
if (active->thumbnail()) {
|
||||
|
@ -728,7 +731,9 @@ bool DocumentData::videoThumbnailFailed() const {
|
|||
}
|
||||
|
||||
void DocumentData::loadVideoThumbnail(Data::FileOrigin origin) {
|
||||
if (_videoThumbnailLoader || (_flags & Flag::VideoThumbnailFailed)) {
|
||||
if (_videoThumbnailLoader
|
||||
|| (_flags & Flag::VideoThumbnailFailed)
|
||||
|| !_videoThumbnailLocation.valid()) {
|
||||
return;
|
||||
} else if (const auto active = activeMediaView()) {
|
||||
if (!active->videoThumbnailContent().isEmpty()) {
|
||||
|
|
|
@ -85,6 +85,56 @@ enum class FileType {
|
|||
|
||||
} // 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)
|
||||
: _owner(owner) {
|
||||
}
|
||||
|
|
|
@ -11,8 +11,34 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
class FileLoader;
|
||||
|
||||
namespace Media {
|
||||
namespace Clip {
|
||||
enum Notification : int;
|
||||
class ReaderPointer;
|
||||
} // namespace Clip
|
||||
} // namespace Media
|
||||
|
||||
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 {
|
||||
public:
|
||||
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 {
|
||||
const auto document = getShownDocument();
|
||||
const auto displayLoading = document->displayLoading();
|
||||
const auto useVideoThumbnail = document->hasVideoThumbnail();
|
||||
ensureDataMediaCreated(document);
|
||||
if (!useVideoThumbnail) {
|
||||
_dataMedia->automaticLoad(fileOrigin(), nullptr);
|
||||
}
|
||||
const auto preview = Data::VideoPreviewState(_dataMedia.get());
|
||||
preview.automaticLoad(fileOrigin());
|
||||
|
||||
const auto loaded = useVideoThumbnail
|
||||
? !_dataMedia->videoThumbnailContent().isEmpty()
|
||||
: _dataMedia->loaded();
|
||||
const auto loading = useVideoThumbnail
|
||||
? document->videoThumbnailLoading()
|
||||
: document->loading();
|
||||
const auto loaded = preview.loaded();
|
||||
const auto loading = preview.loading();
|
||||
if (loaded
|
||||
&& !_gif
|
||||
&& !_gif.isBad()
|
||||
&& CanPlayInline(document)) {
|
||||
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->_gif = useVideoThumbnail
|
||||
? Media::Clip::MakeReader(
|
||||
_dataMedia->videoThumbnailContent(),
|
||||
callback)
|
||||
: Media::Clip::MakeReader(
|
||||
_dataMedia.get(),
|
||||
FullMsgId(),
|
||||
callback);
|
||||
});
|
||||
}
|
||||
|
||||
const auto animating = (_gif && _gif->started());
|
||||
if (displayLoading) {
|
||||
ensureAnimation();
|
||||
if (!_animation->radial.animating()) {
|
||||
_animation->radial.start(_dataMedia->progress()); // #TODO video_thumbs
|
||||
_animation->radial.start(_dataMedia->progress());
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (useVideoThumbnail) {
|
||||
AssertIsDebug();
|
||||
|
||||
AssertIsDebug();
|
||||
if (preview.usingThumbnail()) {
|
||||
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.;
|
||||
if (_animation && _animation->_a_over.animating()) {
|
||||
auto over = _animation->_a_over.value(1.);
|
||||
|
@ -269,10 +259,11 @@ void Gif::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
|||
bool wasactive = (_state & StateFlag::Over);
|
||||
if (active != wasactive) {
|
||||
ensureDataMediaCreated(getShownDocument());
|
||||
if (!_dataMedia->loaded()) { // #TODO video_thumbs
|
||||
const auto preview = Data::VideoPreviewState(_dataMedia.get());
|
||||
if (!preview.usingThumbnail() && !preview.loaded()) {
|
||||
ensureAnimation();
|
||||
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) {
|
||||
_state |= StateFlag::Over;
|
||||
|
@ -369,7 +360,8 @@ bool Gif::isRadialAnimation() const {
|
|||
return true;
|
||||
} else {
|
||||
ensureDataMediaCreated(getShownDocument());
|
||||
if (_dataMedia->loaded()) { // #TODO video_thumbs
|
||||
const auto preview = Data::VideoPreviewState(_dataMedia.get());
|
||||
if (preview.usingThumbnail() || preview.loaded()) {
|
||||
_animation = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -382,7 +374,7 @@ void Gif::radialAnimationCallback(crl::time now) const {
|
|||
ensureDataMediaCreated(document);
|
||||
const auto updated = [&] {
|
||||
return _animation->radial.update(
|
||||
_dataMedia->progress(), // #TODO video_thumbs
|
||||
_dataMedia->progress(),
|
||||
!document->loading() || _dataMedia->loaded(),
|
||||
now);
|
||||
}();
|
||||
|
|
|
@ -275,14 +275,17 @@ bool Result::onChoose(Layout::ItemBase *layout) {
|
|||
_type == Type::Gif)) {
|
||||
if (_type == Type::Gif) {
|
||||
const auto media = _document->activeMediaView();
|
||||
if (!media || media->loaded()) {
|
||||
const auto preview = Data::VideoPreviewState(media.get());
|
||||
if (!media || preview.loaded()) {
|
||||
return true;
|
||||
} else if (_document->loading()) {
|
||||
_document->cancel();
|
||||
} else {
|
||||
DocumentSaveClickHandler::Save(
|
||||
Data::FileOriginSavedGifs(),
|
||||
_document);
|
||||
} else if (!preview.usingThumbnail()) {
|
||||
if (preview.loading()) {
|
||||
_document->cancel();
|
||||
} else {
|
||||
DocumentSaveClickHandler::Save(
|
||||
Data::FileOriginSavedGifs(),
|
||||
_document);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -40,13 +40,13 @@ struct FrameRequest {
|
|||
RectParts corners = RectPart::AllCorners;
|
||||
};
|
||||
|
||||
enum ReaderSteps {
|
||||
enum ReaderSteps : int {
|
||||
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
|
||||
WaitingForFirstFrameStep = -1, // before ReaderPrivate got the frame request and started waiting for the 1-2 delay
|
||||
};
|
||||
|
||||
enum Notification {
|
||||
enum Notification : int {
|
||||
NotificationReinit,
|
||||
NotificationRepaint,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue