init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/chat/attach/attach_single_media_preview.h"
|
||||
|
||||
#include "editor/photo_editor_common.h"
|
||||
#include "ui/chat/attach/attach_prepare.h"
|
||||
#include "core/mime_type.h"
|
||||
#include "lottie/lottie_single_player.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
SingleMediaPreview *SingleMediaPreview::Create(
|
||||
QWidget *parent,
|
||||
const style::ComposeControls &st,
|
||||
Fn<bool()> gifPaused,
|
||||
const PreparedFile &file,
|
||||
Fn<bool(AttachActionType)> actionAllowed,
|
||||
AttachControls::Type type) {
|
||||
auto preview = QImage();
|
||||
auto animated = false;
|
||||
auto animationPreview = false;
|
||||
auto hasModifications = false;
|
||||
if (const auto image = std::get_if<PreparedFileInformation::Image>(
|
||||
&file.information->media)) {
|
||||
preview = Editor::ImageModified(image->data, image->modifications);
|
||||
animated = animationPreview = image->animated;
|
||||
hasModifications = !image->modifications.empty();
|
||||
} else if (const auto video = std::get_if<PreparedFileInformation::Video>(
|
||||
&file.information->media)) {
|
||||
preview = file.videoCover
|
||||
? file.videoCover->preview
|
||||
: video->thumbnail;
|
||||
animated = true;
|
||||
animationPreview = video->isGifv;
|
||||
}
|
||||
if (preview.isNull()) {
|
||||
return nullptr;
|
||||
} else if (!animated
|
||||
&& !ValidateThumbDimensions(preview.width(), preview.height())
|
||||
&& !hasModifications) {
|
||||
return nullptr;
|
||||
}
|
||||
return CreateChild<SingleMediaPreview>(
|
||||
parent,
|
||||
st,
|
||||
std::move(gifPaused),
|
||||
preview,
|
||||
animated,
|
||||
Core::IsMimeSticker(file.information->filemime),
|
||||
file.spoiler,
|
||||
animationPreview ? file.path : QString(),
|
||||
type,
|
||||
std::move(actionAllowed));
|
||||
}
|
||||
|
||||
SingleMediaPreview::SingleMediaPreview(
|
||||
QWidget *parent,
|
||||
const style::ComposeControls &st,
|
||||
Fn<bool()> gifPaused,
|
||||
QImage preview,
|
||||
bool animated,
|
||||
bool sticker,
|
||||
bool spoiler,
|
||||
const QString &animatedPreviewPath,
|
||||
AttachControls::Type type,
|
||||
Fn<bool(AttachActionType)> actionAllowed)
|
||||
: AbstractSingleMediaPreview(parent, st, type, std::move(actionAllowed))
|
||||
, _gifPaused(std::move(gifPaused))
|
||||
, _sticker(sticker) {
|
||||
Expects(!preview.isNull());
|
||||
setAnimated(animated);
|
||||
|
||||
preparePreview(preview);
|
||||
prepareAnimatedPreview(animatedPreviewPath, animated);
|
||||
setSpoiler(spoiler);
|
||||
}
|
||||
|
||||
bool SingleMediaPreview::supportsSpoilers() const {
|
||||
return !_sticker || sendWay().sendImagesAsPhotos();
|
||||
}
|
||||
|
||||
bool SingleMediaPreview::drawBackground() const {
|
||||
return !_sticker;
|
||||
}
|
||||
|
||||
bool SingleMediaPreview::tryPaintAnimation(QPainter &p) {
|
||||
if (_gifPreview && _gifPreview->started()) {
|
||||
const auto paused = _gifPaused();
|
||||
const auto frame = _gifPreview->current({
|
||||
.frame = QSize(previewWidth(), previewHeight()),
|
||||
}, paused ? 0 : crl::now());
|
||||
p.drawImage(previewLeft(), previewTop(), frame);
|
||||
return true;
|
||||
} else if (_lottiePreview && _lottiePreview->ready()) {
|
||||
const auto frame = _lottiePreview->frame();
|
||||
const auto size = frame.size() / style::DevicePixelRatio();
|
||||
p.drawImage(
|
||||
QRect(
|
||||
previewLeft() + (previewWidth() - size.width()) / 2,
|
||||
(previewHeight() - size.height()) / 2,
|
||||
size.width(),
|
||||
size.height()),
|
||||
frame);
|
||||
_lottiePreview->markFrameShown();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SingleMediaPreview::isAnimatedPreviewReady() const {
|
||||
return _gifPreview || _lottiePreview;
|
||||
}
|
||||
|
||||
void SingleMediaPreview::prepareAnimatedPreview(
|
||||
const QString &animatedPreviewPath,
|
||||
bool animated) {
|
||||
if (_sticker && animated) {
|
||||
const auto box = QSize(previewWidth(), previewHeight())
|
||||
* style::DevicePixelRatio();
|
||||
_lottiePreview = std::make_unique<Lottie::SinglePlayer>(
|
||||
Lottie::ReadContent(QByteArray(), animatedPreviewPath),
|
||||
Lottie::FrameRequest{ box });
|
||||
_lottiePreview->updates(
|
||||
) | rpl::on_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
} else if (!animatedPreviewPath.isEmpty()) {
|
||||
auto callback = [=](Media::Clip::Notification notification) {
|
||||
clipCallback(notification);
|
||||
};
|
||||
_gifPreview = Media::Clip::MakeReader(
|
||||
animatedPreviewPath,
|
||||
std::move(callback));
|
||||
}
|
||||
}
|
||||
|
||||
void SingleMediaPreview::clipCallback(
|
||||
Media::Clip::Notification notification) {
|
||||
using namespace Media::Clip;
|
||||
switch (notification) {
|
||||
case Notification::Reinit: {
|
||||
if (_gifPreview && _gifPreview->state() == State::Error) {
|
||||
_gifPreview.setBad();
|
||||
}
|
||||
|
||||
if (_gifPreview && _gifPreview->ready() && !_gifPreview->started()) {
|
||||
_gifPreview->start({
|
||||
.frame = QSize(previewWidth(), previewHeight()),
|
||||
});
|
||||
}
|
||||
|
||||
update();
|
||||
} break;
|
||||
|
||||
case Notification::Repaint: {
|
||||
if (_gifPreview && !_gifPreview->currentDisplayed()) {
|
||||
update();
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
Reference in New Issue
Block a user