mirror of https://github.com/procxx/kepka.git
Added ability to edit GIFs.
- Added to Media::Clip::MakeReader new constructor to create animated preview with remoteContent.
This commit is contained in:
parent
49681525ed
commit
fb847135b5
|
@ -4659,6 +4659,9 @@ void ApiWrap::editUploadedFile(
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!item->media()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto sentEntities = TextUtilities::EntitiesToMTP(
|
auto sentEntities = TextUtilities::EntitiesToMTP(
|
||||||
item->originalText().entities,
|
item->originalText().entities,
|
||||||
|
@ -4669,21 +4672,31 @@ void ApiWrap::editUploadedFile(
|
||||||
flagsEditMsg |= MTPmessages_EditMessage::Flag::f_entities;
|
flagsEditMsg |= MTPmessages_EditMessage::Flag::f_entities;
|
||||||
flagsEditMsg |= MTPmessages_EditMessage::Flag::f_media;
|
flagsEditMsg |= MTPmessages_EditMessage::Flag::f_media;
|
||||||
|
|
||||||
MTPinputMedia media = MTP_inputMediaEmpty();
|
const auto media = [&]() -> std::optional<MTPInputMedia> {
|
||||||
|
if (!isDocument) {
|
||||||
|
if (!item->media()->photo()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
return MTP_inputMediaUploadedPhoto(
|
||||||
|
MTP_flags(0),
|
||||||
|
file,
|
||||||
|
MTPVector<MTPInputDocument>(),
|
||||||
|
MTP_int(0));
|
||||||
|
}
|
||||||
|
|
||||||
if (isDocument) {
|
|
||||||
const auto document = item->media()->document();
|
const auto document = item->media()->document();
|
||||||
if (!document) {
|
if (!document) {
|
||||||
return;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto flags = MTPDinputMediaUploadedDocument::Flags(0)
|
const auto flags = MTPDinputMediaUploadedDocument::Flags(0)
|
||||||
| (thumb
|
| (thumb
|
||||||
? MTPDinputMediaUploadedDocument::Flag::f_thumb
|
? MTPDinputMediaUploadedDocument::Flag::f_thumb
|
||||||
: MTPDinputMediaUploadedDocument::Flag(0))
|
: MTPDinputMediaUploadedDocument::Flag(0))
|
||||||
// Never edit video as gif.
|
| (item->groupId()
|
||||||
| MTPDinputMediaUploadedDocument::Flag::f_nosound_video;
|
? MTPDinputMediaUploadedDocument::Flag::f_nosound_video
|
||||||
media = MTP_inputMediaUploadedDocument(
|
: MTPDinputMediaUploadedDocument::Flag(0));
|
||||||
|
return MTP_inputMediaUploadedDocument(
|
||||||
MTP_flags(flags),
|
MTP_flags(flags),
|
||||||
file,
|
file,
|
||||||
thumb ? *thumb : MTPInputFile(),
|
thumb ? *thumb : MTPInputFile(),
|
||||||
|
@ -4691,16 +4704,10 @@ void ApiWrap::editUploadedFile(
|
||||||
ComposeSendingDocumentAttributes(document),
|
ComposeSendingDocumentAttributes(document),
|
||||||
MTPVector<MTPInputDocument>(),
|
MTPVector<MTPInputDocument>(),
|
||||||
MTP_int(0));
|
MTP_int(0));
|
||||||
} else {
|
}();
|
||||||
const auto photo = item->media()->photo();
|
|
||||||
if (!photo) {
|
if (!media) {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
media = MTP_inputMediaUploadedPhoto(
|
|
||||||
MTP_flags(0),
|
|
||||||
file,
|
|
||||||
MTPVector<MTPInputDocument>(),
|
|
||||||
MTP_int(0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
request(MTPmessages_EditMessage(
|
request(MTPmessages_EditMessage(
|
||||||
|
@ -4708,7 +4715,7 @@ void ApiWrap::editUploadedFile(
|
||||||
item->history()->peer->input,
|
item->history()->peer->input,
|
||||||
MTP_int(item->id),
|
MTP_int(item->id),
|
||||||
MTP_string(item->originalText().text),
|
MTP_string(item->originalText().text),
|
||||||
media,
|
*media,
|
||||||
MTPReplyMarkup(),
|
MTPReplyMarkup(),
|
||||||
sentEntities
|
sentEntities
|
||||||
)).done([=](const MTPUpdates &result) {
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
|
|
@ -298,10 +298,10 @@ void EditCaptionBox::updateEmojiPanelGeometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditCaptionBox::prepareGifPreview(DocumentData* document) {
|
void EditCaptionBox::prepareGifPreview(DocumentData* document) {
|
||||||
const auto newPath = getNewMediaPath();
|
const auto isListEmpty = _preparedList.files.empty();
|
||||||
if (_gifPreview) {
|
if (_gifPreview) {
|
||||||
return;
|
return;
|
||||||
} else if (!document && newPath.isEmpty()) {
|
} else if (!document && isListEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto callback = [=](Media::Clip::Notification notification) {
|
const auto callback = [=](Media::Clip::Notification notification) {
|
||||||
|
@ -312,10 +312,17 @@ void EditCaptionBox::prepareGifPreview(DocumentData* document) {
|
||||||
document,
|
document,
|
||||||
_msgId,
|
_msgId,
|
||||||
callback);
|
callback);
|
||||||
} else if (!newPath.isEmpty()) {
|
} else if (!isListEmpty) {
|
||||||
_gifPreview = Media::Clip::MakeReader(
|
const auto file = &_preparedList.files.front();
|
||||||
newPath,
|
if (file->path.isEmpty()) {
|
||||||
callback);
|
_gifPreview = Media::Clip::MakeReader(
|
||||||
|
file->content,
|
||||||
|
callback);
|
||||||
|
} else {
|
||||||
|
_gifPreview = Media::Clip::MakeReader(
|
||||||
|
file->path,
|
||||||
|
callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_gifPreview) _gifPreview->setAutoplay();
|
if (_gifPreview) _gifPreview->setAutoplay();
|
||||||
}
|
}
|
||||||
|
@ -329,6 +336,23 @@ void EditCaptionBox::clipCallback(Media::Clip::Notification notification) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_gifPreview && _gifPreview->ready() && !_gifPreview->started()) {
|
if (_gifPreview && _gifPreview->ready() && !_gifPreview->started()) {
|
||||||
|
const auto calculateGifDimensions = [&]() {
|
||||||
|
const auto scaled = QSize(
|
||||||
|
_gifPreview->width(),
|
||||||
|
_gifPreview->height()).scaled(
|
||||||
|
st::sendMediaPreviewSize * cIntRetinaFactor(),
|
||||||
|
st::confirmMaxHeight * cIntRetinaFactor(),
|
||||||
|
Qt::KeepAspectRatio);
|
||||||
|
_thumbw = _gifw = scaled.width();
|
||||||
|
_thumbh = _gifh = scaled.height();
|
||||||
|
_thumbx = _gifx = (st::boxWideWidth - _gifw) / 2;
|
||||||
|
updateBoxSize();
|
||||||
|
};
|
||||||
|
// If gif file is not mp4,
|
||||||
|
// Its dimension values will be known only after reading.
|
||||||
|
if (_gifw <= 0 || _gifh <= 0) {
|
||||||
|
calculateGifDimensions();
|
||||||
|
}
|
||||||
const auto s = QSize(_gifw, _gifh);
|
const auto s = QSize(_gifw, _gifh);
|
||||||
_gifPreview->start(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, RectPart::None);
|
_gifPreview->start(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, RectPart::None);
|
||||||
}
|
}
|
||||||
|
@ -362,17 +386,19 @@ void EditCaptionBox::updateEditPreview() {
|
||||||
_thumbw = _thumbh = _thumbx = 0;
|
_thumbw = _thumbh = _thumbx = 0;
|
||||||
_gifw = _gifh = _gifx = 0;
|
_gifw = _gifh = _gifx = 0;
|
||||||
|
|
||||||
|
auto isGif = false;
|
||||||
auto shouldAsDoc = true;
|
auto shouldAsDoc = true;
|
||||||
if (const auto image = base::get_if<Info::Image>(fileMedia)) {
|
if (const auto image = base::get_if<Info::Image>(fileMedia)) {
|
||||||
shouldAsDoc = !Storage::ValidateThumbDimensions(
|
shouldAsDoc = !Storage::ValidateThumbDimensions(
|
||||||
image->data.width(),
|
image->data.width(),
|
||||||
image->data.height());
|
image->data.height());
|
||||||
_photo = !shouldAsDoc;
|
isGif = image->animated;
|
||||||
|
_animated = isGif;
|
||||||
|
_photo = !isGif && !shouldAsDoc;
|
||||||
_isImage = true;
|
_isImage = true;
|
||||||
} else if (const auto video = base::get_if<Info::Video>(fileMedia)) {
|
} else if (const auto video = base::get_if<Info::Video>(fileMedia)) {
|
||||||
|
isGif = video->isGifv;
|
||||||
_animated = true;
|
_animated = true;
|
||||||
// Never edit video as gif.
|
|
||||||
video->isGifv = false;
|
|
||||||
shouldAsDoc = false;
|
shouldAsDoc = false;
|
||||||
}
|
}
|
||||||
if (shouldAsDoc) {
|
if (shouldAsDoc) {
|
||||||
|
@ -405,6 +431,12 @@ void EditCaptionBox::updateEditPreview() {
|
||||||
_thumbw = _thumb.width() / cIntRetinaFactor();
|
_thumbw = _thumb.width() / cIntRetinaFactor();
|
||||||
_thumbh = _thumb.height() / cIntRetinaFactor();
|
_thumbh = _thumb.height() / cIntRetinaFactor();
|
||||||
_thumbx = (st::boxWideWidth - _thumbw) / 2;
|
_thumbx = (st::boxWideWidth - _thumbw) / 2;
|
||||||
|
if (isGif) {
|
||||||
|
_gifw = _thumbw;
|
||||||
|
_gifh = _thumbh;
|
||||||
|
_gifx = _thumbx;
|
||||||
|
prepareGifPreview();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateEditMediaButton();
|
updateEditMediaButton();
|
||||||
captionResized();
|
captionResized();
|
||||||
|
@ -427,8 +459,7 @@ void EditCaptionBox::createEditMediaButton() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto isValidFile = [](QString mimeType) {
|
const auto isValidFile = [](QString mimeType) {
|
||||||
if (mimeType == qstr("image/webp")
|
if (mimeType == qstr("image/webp")) {
|
||||||
|| mimeType == qstr("image/gif")) {
|
|
||||||
Ui::show(
|
Ui::show(
|
||||||
Box<InformBox>(lang(lng_edit_media_invalid_file)),
|
Box<InformBox>(lang(lng_edit_media_invalid_file)),
|
||||||
LayerOption::KeepOther);
|
LayerOption::KeepOther);
|
||||||
|
@ -477,8 +508,10 @@ void EditCaptionBox::createEditMediaButton() {
|
||||||
const auto valid = media->match([&](const Info::Image &data) {
|
const auto valid = media->match([&](const Info::Image &data) {
|
||||||
return Storage::ValidateThumbDimensions(
|
return Storage::ValidateThumbDimensions(
|
||||||
data.data.width(),
|
data.data.width(),
|
||||||
data.data.height());
|
data.data.height())
|
||||||
}, [&](const Info::Video &data) {
|
&& !data.animated;
|
||||||
|
}, [&](Info::Video &data) {
|
||||||
|
data.isGifv = false;
|
||||||
return true;
|
return true;
|
||||||
}, [](auto &&other) {
|
}, [](auto &&other) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -665,7 +665,6 @@ bool MediaFile::allowsEditCaption() const {
|
||||||
bool MediaFile::allowsEditMedia() const {
|
bool MediaFile::allowsEditMedia() const {
|
||||||
return !_document->isVideoMessage()
|
return !_document->isVideoMessage()
|
||||||
&& !_document->sticker()
|
&& !_document->sticker()
|
||||||
&& !_document->isGifv()
|
|
||||||
&& !_document->isVoiceMessage();
|
&& !_document->isVoiceMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,13 @@ Reader::Reader(not_null<DocumentData*> document, FullMsgId msgId, Callback &&cal
|
||||||
init(document->location(), document->data());
|
init(document->location(), document->data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reader::Reader(const QByteArray &data, Callback &&callback, Mode mode, crl::time seekMs)
|
||||||
|
: _callback(std::move(callback))
|
||||||
|
, _mode(mode)
|
||||||
|
, _seekPositionMs(seekMs) {
|
||||||
|
init(FileLocation(QString()), data);
|
||||||
|
}
|
||||||
|
|
||||||
void Reader::init(const FileLocation &location, const QByteArray &data) {
|
void Reader::init(const FileLocation &location, const QByteArray &data) {
|
||||||
if (threads.size() < ClipThreadsCount) {
|
if (threads.size() < ClipThreadsCount) {
|
||||||
_threadIndex = threads.size();
|
_threadIndex = threads.size();
|
||||||
|
|
|
@ -51,6 +51,7 @@ public:
|
||||||
|
|
||||||
Reader(const QString &filepath, Callback &&callback, Mode mode = Mode::Gif, crl::time seekMs = 0);
|
Reader(const QString &filepath, Callback &&callback, Mode mode = Mode::Gif, crl::time seekMs = 0);
|
||||||
Reader(not_null<DocumentData*> document, FullMsgId msgId, Callback &&callback, Mode mode = Mode::Gif, crl::time seekMs = 0);
|
Reader(not_null<DocumentData*> document, FullMsgId msgId, Callback &&callback, Mode mode = Mode::Gif, crl::time seekMs = 0);
|
||||||
|
Reader(const QByteArray &data, Callback &&callback, Mode mode = Mode::Gif, crl::time seekMs = 0);
|
||||||
|
|
||||||
// Reader can be already deleted.
|
// Reader can be already deleted.
|
||||||
static void callback(Reader *reader, qint32 threadIndex, qint32 notification);
|
static void callback(Reader *reader, qint32 threadIndex, qint32 notification);
|
||||||
|
|
Loading…
Reference in New Issue