mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 22:54:01 +02:00
Use / cache the same sticker / effect size in preview.
This commit is contained in:
parent
693d886d81
commit
ad3c6ebb1e
8 changed files with 164 additions and 125 deletions
|
@ -7,15 +7,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "boxes/sticker_preview_box.h"
|
#include "boxes/sticker_preview_box.h"
|
||||||
|
|
||||||
|
#include "chat_helpers/stickers_lottie.h"
|
||||||
|
#include "chat_helpers/stickers_emoji_pack.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_document_media.h"
|
#include "data/data_document_media.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
#include "ui/chat/chat_theme.h"
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/layers/generic_box.h"
|
#include "ui/layers/generic_box.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/wrap/padding_wrap.h"
|
#include "ui/wrap/padding_wrap.h"
|
||||||
#include "lottie/lottie_single_player.h"
|
#include "lottie/lottie_single_player.h"
|
||||||
|
#include "history/view/media/history_view_sticker.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
|
@ -23,7 +27,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kPremiumShift = 0.082;
|
constexpr auto kPremiumShift = 0.082;
|
||||||
constexpr auto kPremiumMultiplier = 1.5;
|
|
||||||
|
|
||||||
struct Preload {
|
struct Preload {
|
||||||
not_null<DocumentData*> document;
|
not_null<DocumentData*> document;
|
||||||
|
@ -57,9 +60,10 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
|
||||||
};
|
};
|
||||||
const auto state = lifetime.make_state<State>();
|
const auto state = lifetime.make_state<State>();
|
||||||
|
|
||||||
const auto lottie = int(size / kPremiumMultiplier);
|
using namespace HistoryView;
|
||||||
const auto lottieSize = QSize(lottie, lottie);
|
const auto document = media->owner();
|
||||||
const auto effectSize = QSize(size, size);
|
const auto lottieSize = Sticker::Size(document);
|
||||||
|
const auto effectSize = Sticker::PremiumEffectSize(document);
|
||||||
const auto createLottieIfReady = [=] {
|
const auto createLottieIfReady = [=] {
|
||||||
if (state->lottie) {
|
if (state->lottie) {
|
||||||
return;
|
return;
|
||||||
|
@ -73,14 +77,17 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto factor = style::DevicePixelRatio();
|
const auto factor = style::DevicePixelRatio();
|
||||||
state->lottie = std::make_unique<Lottie::SinglePlayer>(
|
state->lottie = ChatHelpers::LottiePlayerFromDocument(
|
||||||
Lottie::ReadContent(media->bytes(), document->filepath()),
|
media.get(),
|
||||||
Lottie::FrameRequest{ lottieSize * factor },
|
nullptr,
|
||||||
Lottie::Quality::High);
|
ChatHelpers::StickerLottieSize::MessageHistory,
|
||||||
state->effect = std::make_unique<Lottie::SinglePlayer>(
|
lottieSize * factor,
|
||||||
Lottie::ReadContent(media->videoThumbnailContent(), {}),
|
|
||||||
Lottie::FrameRequest{ effectSize * factor },
|
|
||||||
Lottie::Quality::High);
|
Lottie::Quality::High);
|
||||||
|
state->effect = document->session().emojiStickersPack().effectPlayer(
|
||||||
|
document,
|
||||||
|
media->videoThumbnailContent(),
|
||||||
|
QString(),
|
||||||
|
true);
|
||||||
|
|
||||||
const auto update = [=] { raw->update(); };
|
const auto update = [=] { raw->update(); };
|
||||||
auto &lifetime = raw->lifetime();
|
auto &lifetime = raw->lifetime();
|
||||||
|
@ -104,12 +111,12 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
|
||||||
const auto frame = state->lottie->frameInfo({ lottieSize * factor });
|
const auto frame = state->lottie->frameInfo({ lottieSize * factor });
|
||||||
const auto effect = state->effect->frameInfo(
|
const auto effect = state->effect->frameInfo(
|
||||||
{ effectSize * factor });
|
{ effectSize * factor });
|
||||||
const auto framesCount = !frame.image.isNull()
|
//const auto framesCount = !frame.image.isNull()
|
||||||
? state->lottie->framesCount()
|
// ? state->lottie->framesCount()
|
||||||
: 1;
|
// : 1;
|
||||||
const auto effectsCount = !effect.image.isNull()
|
//const auto effectsCount = !effect.image.isNull()
|
||||||
? state->effect->framesCount()
|
// ? state->effect->framesCount()
|
||||||
: 1;
|
// : 1;
|
||||||
|
|
||||||
const auto left = effectSize.width()
|
const auto left = effectSize.width()
|
||||||
- int(lottieSize.width() * (1. + kPremiumShift));
|
- int(lottieSize.width() * (1. + kPremiumShift));
|
||||||
|
|
|
@ -20,6 +20,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "base/call_delayed.h"
|
#include "base/call_delayed.h"
|
||||||
|
#include "chat_helpers/stickers_lottie.h"
|
||||||
|
#include "history/view/media/history_view_sticker.h"
|
||||||
|
#include "lottie/lottie_single_player.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
@ -29,6 +32,8 @@ namespace Stickers {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kRefreshTimeout = 7200 * crl::time(1000);
|
constexpr auto kRefreshTimeout = 7200 * crl::time(1000);
|
||||||
|
constexpr auto kEmojiCachesCount = 4;
|
||||||
|
constexpr auto kPremiumCachesCount = 8;
|
||||||
|
|
||||||
[[nodiscard]] std::optional<int> IndexFromEmoticon(const QString &emoticon) {
|
[[nodiscard]] std::optional<int> IndexFromEmoticon(const QString &emoticon) {
|
||||||
if (emoticon.size() < 2) {
|
if (emoticon.size() < 2) {
|
||||||
|
@ -201,6 +206,57 @@ auto EmojiPack::animationsForEmoji(EmojiPtr emoji) const
|
||||||
return (i != end(_animations)) ? i->second : empty;
|
return (i != end(_animations)) ? i->second : empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Lottie::SinglePlayer> EmojiPack::effectPlayer(
|
||||||
|
not_null<DocumentData*> document,
|
||||||
|
QByteArray data,
|
||||||
|
QString filepath,
|
||||||
|
bool premium) {
|
||||||
|
// Shortened copy from stickers_lottie module.
|
||||||
|
const auto baseKey = document->bigFileBaseCacheKey();
|
||||||
|
const auto tag = uint8(0);
|
||||||
|
const auto keyShift = ((tag << 4) & 0xF0)
|
||||||
|
| (uint8(ChatHelpers::StickerLottieSize::EmojiInteraction) & 0x0F);
|
||||||
|
const auto key = Storage::Cache::Key{
|
||||||
|
baseKey.high,
|
||||||
|
baseKey.low + keyShift
|
||||||
|
};
|
||||||
|
const auto get = [=](int i, FnMut<void(QByteArray &&cached)> handler) {
|
||||||
|
document->owner().cacheBigFile().get(
|
||||||
|
{ key.high, key.low + i },
|
||||||
|
std::move(handler));
|
||||||
|
};
|
||||||
|
const auto weak = base::make_weak(&document->session());
|
||||||
|
const auto put = [=](int i, QByteArray &&cached) {
|
||||||
|
crl::on_main(weak, [=, data = std::move(cached)]() mutable {
|
||||||
|
weak->data().cacheBigFile().put(
|
||||||
|
{ key.high, key.low + i },
|
||||||
|
std::move(data));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const auto size = premium
|
||||||
|
? HistoryView::Sticker::PremiumEffectSize(document)
|
||||||
|
: HistoryView::Sticker::EmojiEffectSize();
|
||||||
|
const auto request = Lottie::FrameRequest{
|
||||||
|
size * style::DevicePixelRatio(),
|
||||||
|
};
|
||||||
|
auto &weakProvider = _sharedProviders[document];
|
||||||
|
auto shared = [&] {
|
||||||
|
if (const auto result = weakProvider.lock()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const auto result = Lottie::SinglePlayer::SharedProvider(
|
||||||
|
premium ? kPremiumCachesCount : kEmojiCachesCount,
|
||||||
|
get,
|
||||||
|
put,
|
||||||
|
Lottie::ReadContent(data, filepath),
|
||||||
|
request,
|
||||||
|
Lottie::Quality::High);
|
||||||
|
weakProvider = result;
|
||||||
|
return result;
|
||||||
|
}();
|
||||||
|
return std::make_unique<Lottie::SinglePlayer>(std::move(shared), request);
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiPack::refresh() {
|
void EmojiPack::refresh() {
|
||||||
if (_requestId) {
|
if (_requestId) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -21,6 +21,8 @@ class Session;
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
|
||||||
namespace Lottie {
|
namespace Lottie {
|
||||||
|
class SinglePlayer;
|
||||||
|
class FrameProvider;
|
||||||
struct ColorReplacements;
|
struct ColorReplacements;
|
||||||
} // namespace Lottie
|
} // namespace Lottie
|
||||||
|
|
||||||
|
@ -70,6 +72,12 @@ public:
|
||||||
[[nodiscard]] auto animationsForEmoji(EmojiPtr emoji) const
|
[[nodiscard]] auto animationsForEmoji(EmojiPtr emoji) const
|
||||||
-> const base::flat_map<int, not_null<DocumentData*>> &;
|
-> const base::flat_map<int, not_null<DocumentData*>> &;
|
||||||
|
|
||||||
|
[[nodiscard]] std::unique_ptr<Lottie::SinglePlayer> effectPlayer(
|
||||||
|
not_null<DocumentData*> document,
|
||||||
|
QByteArray data,
|
||||||
|
QString filepath,
|
||||||
|
bool premium);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ImageLoader;
|
class ImageLoader;
|
||||||
|
|
||||||
|
@ -103,6 +111,10 @@ private:
|
||||||
base::flat_map<int, not_null<DocumentData*>>> _animations;
|
base::flat_map<int, not_null<DocumentData*>>> _animations;
|
||||||
mtpRequestId _animationsRequestId = 0;
|
mtpRequestId _animationsRequestId = 0;
|
||||||
|
|
||||||
|
base::flat_map<
|
||||||
|
not_null<DocumentData*>,
|
||||||
|
std::weak_ptr<Lottie::FrameProvider>> _sharedProviders;
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
#include "history/view/media/history_view_sticker.h"
|
#include "history/view/media/history_view_sticker.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
#include "chat_helpers/stickers_emoji_pack.h"
|
||||||
#include "chat_helpers/emoji_interactions.h"
|
#include "chat_helpers/emoji_interactions.h"
|
||||||
#include "chat_helpers/stickers_lottie.h"
|
#include "chat_helpers/stickers_lottie.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
@ -24,11 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kEmojiMultiplier = 3;
|
|
||||||
constexpr auto kPremiumShift = 0.082;
|
constexpr auto kPremiumShift = 0.082;
|
||||||
constexpr auto kPremiumMultiplier = 1.5;
|
|
||||||
constexpr auto kEmojiCachesCount = 4;
|
|
||||||
constexpr auto kPremiumCachesCount = 8;
|
|
||||||
constexpr auto kMaxPlays = 5;
|
constexpr auto kMaxPlays = 5;
|
||||||
constexpr auto kMaxPlaysWithSmallDelay = 3;
|
constexpr auto kMaxPlaysWithSmallDelay = 3;
|
||||||
constexpr auto kSmallDelay = crl::time(200);
|
constexpr auto kSmallDelay = crl::time(200);
|
||||||
|
@ -59,9 +56,6 @@ EmojiInteractions::EmojiInteractions(
|
||||||
ranges::remove(_delayed, view, &Delayed::view),
|
ranges::remove(_delayed, view, &Delayed::view),
|
||||||
end(_delayed));
|
end(_delayed));
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
_emojiSize = Sticker::EmojiSize();
|
|
||||||
_premiumSize = Sticker::Size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EmojiInteractions::~EmojiInteractions() {
|
EmojiInteractions::~EmojiInteractions() {
|
||||||
|
@ -172,9 +166,16 @@ void EmojiInteractions::play(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lottie = preparePlayer(document, data, filepath, premium);
|
auto lottie = document->session().emojiStickersPack().effectPlayer(
|
||||||
|
document,
|
||||||
|
data,
|
||||||
|
filepath,
|
||||||
|
premium);
|
||||||
|
|
||||||
const auto shift = premium ? QPoint() : GenerateRandomShift(_emojiSize);
|
const auto inner = premium
|
||||||
|
? HistoryView::Sticker::Size(document)
|
||||||
|
: HistoryView::Sticker::EmojiSize();
|
||||||
|
const auto shift = premium ? QPoint() : GenerateRandomShift(inner);
|
||||||
const auto raw = lottie.get();
|
const auto raw = lottie.get();
|
||||||
lottie->updates(
|
lottie->updates(
|
||||||
) | rpl::start_with_next([=](Lottie::Update update) {
|
) | rpl::start_with_next([=](Lottie::Update update) {
|
||||||
|
@ -183,9 +184,7 @@ void EmojiInteractions::play(
|
||||||
const auto i = ranges::find(_plays, raw, [](const Play &p) {
|
const auto i = ranges::find(_plays, raw, [](const Play &p) {
|
||||||
return p.lottie.get();
|
return p.lottie.get();
|
||||||
});
|
});
|
||||||
const auto rect = computeRect(
|
const auto rect = computeRect(*i).translated(shift);
|
||||||
i->view,
|
|
||||||
i->premium).translated(shift);
|
|
||||||
if (rect.y() + rect.height() >= _visibleTop
|
if (rect.y() + rect.height() >= _visibleTop
|
||||||
&& rect.y() <= _visibleBottom) {
|
&& rect.y() <= _visibleBottom) {
|
||||||
_updateRequests.fire_copy(rect);
|
_updateRequests.fire_copy(rect);
|
||||||
|
@ -199,6 +198,10 @@ void EmojiInteractions::play(
|
||||||
.view = view,
|
.view = view,
|
||||||
.lottie = std::move(lottie),
|
.lottie = std::move(lottie),
|
||||||
.shift = shift,
|
.shift = shift,
|
||||||
|
.inner = inner,
|
||||||
|
.outer = (premium
|
||||||
|
? HistoryView::Sticker::PremiumEffectSize(document)
|
||||||
|
: HistoryView::Sticker::EmojiEffectSize()),
|
||||||
.premium = premium,
|
.premium = premium,
|
||||||
});
|
});
|
||||||
if (incoming) {
|
if (incoming) {
|
||||||
|
@ -211,60 +214,6 @@ void EmojiInteractions::play(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize EmojiInteractions::sizeFor(bool premium) const {
|
|
||||||
return premium
|
|
||||||
? (_premiumSize * kPremiumMultiplier)
|
|
||||||
: (_emojiSize * kEmojiMultiplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Lottie::SinglePlayer> EmojiInteractions::preparePlayer(
|
|
||||||
not_null<DocumentData*> document,
|
|
||||||
QByteArray data,
|
|
||||||
QString filepath,
|
|
||||||
bool premium) {
|
|
||||||
// Shortened copy from stickers_lottie module.
|
|
||||||
const auto baseKey = document->bigFileBaseCacheKey();
|
|
||||||
const auto tag = uint8(0);
|
|
||||||
const auto keyShift = ((tag << 4) & 0xF0)
|
|
||||||
| (uint8(ChatHelpers::StickerLottieSize::EmojiInteraction) & 0x0F);
|
|
||||||
const auto key = Storage::Cache::Key{
|
|
||||||
baseKey.high,
|
|
||||||
baseKey.low + keyShift
|
|
||||||
};
|
|
||||||
const auto get = [=](int i, FnMut<void(QByteArray &&cached)> handler) {
|
|
||||||
document->owner().cacheBigFile().get(
|
|
||||||
{ key.high, key.low + i },
|
|
||||||
std::move(handler));
|
|
||||||
};
|
|
||||||
const auto weak = base::make_weak(&document->session());
|
|
||||||
const auto put = [=](int i, QByteArray &&cached) {
|
|
||||||
crl::on_main(weak, [=, data = std::move(cached)]() mutable {
|
|
||||||
weak->data().cacheBigFile().put(
|
|
||||||
{ key.high, key.low + i },
|
|
||||||
std::move(data));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const auto request = Lottie::FrameRequest{
|
|
||||||
sizeFor(premium) * style::DevicePixelRatio(),
|
|
||||||
};
|
|
||||||
auto &weakProvider = _sharedProviders[document];
|
|
||||||
auto shared = [&] {
|
|
||||||
if (const auto result = weakProvider.lock()) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
const auto result = Lottie::SinglePlayer::SharedProvider(
|
|
||||||
premium ? kPremiumCachesCount : kEmojiCachesCount,
|
|
||||||
get,
|
|
||||||
put,
|
|
||||||
Lottie::ReadContent(data, filepath),
|
|
||||||
request,
|
|
||||||
Lottie::Quality::High);
|
|
||||||
weakProvider = result;
|
|
||||||
return result;
|
|
||||||
}();
|
|
||||||
return std::make_unique<Lottie::SinglePlayer>(std::move(shared), request);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmojiInteractions::visibleAreaUpdated(
|
void EmojiInteractions::visibleAreaUpdated(
|
||||||
int visibleTop,
|
int visibleTop,
|
||||||
int visibleBottom) {
|
int visibleBottom) {
|
||||||
|
@ -272,14 +221,13 @@ void EmojiInteractions::visibleAreaUpdated(
|
||||||
_visibleBottom = visibleBottom;
|
_visibleBottom = visibleBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect EmojiInteractions::computeRect(
|
QRect EmojiInteractions::computeRect(const Play &play) const {
|
||||||
not_null<const Element*> view,
|
const auto view = play.view;
|
||||||
bool premium) const {
|
|
||||||
const auto fullWidth = view->width();
|
const auto fullWidth = view->width();
|
||||||
const auto sticker = premium ? _premiumSize : _emojiSize;
|
const auto sticker = play.inner;
|
||||||
const auto size = sizeFor(premium);
|
const auto size = play.outer;
|
||||||
const auto shift = premium
|
const auto shift = play.premium
|
||||||
? int(_premiumSize.width() * kPremiumShift)
|
? int(sticker.width() * kPremiumShift)
|
||||||
: (size.width() / 40);
|
: (size.width() / 40);
|
||||||
const auto inner = view->innerGeometry();
|
const auto inner = view->innerGeometry();
|
||||||
const auto rightAligned = view->hasOutLayout()
|
const auto rightAligned = view->hasOutLayout()
|
||||||
|
@ -292,7 +240,7 @@ QRect EmojiInteractions::computeRect(
|
||||||
return QRect();
|
return QRect();
|
||||||
}
|
}
|
||||||
const auto top = viewTop + (sticker.height() - size.height()) / 2;
|
const auto top = viewTop + (sticker.height() - size.height()) / 2;
|
||||||
return QRect(QPoint(left, top), size);
|
return QRect(QPoint(left, top), size).translated(play.shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiInteractions::paint(QPainter &p) {
|
void EmojiInteractions::paint(QPainter &p) {
|
||||||
|
@ -302,7 +250,7 @@ void EmojiInteractions::paint(QPainter &p) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto request = Lottie::FrameRequest();
|
auto request = Lottie::FrameRequest();
|
||||||
request.box = sizeFor(play.premium) * factor;
|
request.box = play.outer * factor;
|
||||||
const auto rightAligned = play.view->hasOutLayout()
|
const auto rightAligned = play.view->hasOutLayout()
|
||||||
&& !play.view->delegate()->elementIsChatWide();
|
&& !play.view->delegate()->elementIsChatWide();
|
||||||
if (!rightAligned) {
|
if (!rightAligned) {
|
||||||
|
@ -315,9 +263,7 @@ void EmojiInteractions::paint(QPainter &p) {
|
||||||
play.framesCount = information.framesCount;
|
play.framesCount = information.framesCount;
|
||||||
play.frameRate = information.frameRate;
|
play.frameRate = information.frameRate;
|
||||||
}
|
}
|
||||||
const auto rect = computeRect(
|
const auto rect = computeRect(play);
|
||||||
play.view,
|
|
||||||
play.premium).translated(play.shift);
|
|
||||||
if (play.started && !play.frame) {
|
if (play.started && !play.frame) {
|
||||||
play.finished = true;
|
play.finished = true;
|
||||||
_updateRequests.fire_copy(rect);
|
_updateRequests.fire_copy(rect);
|
||||||
|
|
|
@ -17,7 +17,6 @@ struct EmojiInteractionPlayRequest;
|
||||||
|
|
||||||
namespace Lottie {
|
namespace Lottie {
|
||||||
class SinglePlayer;
|
class SinglePlayer;
|
||||||
class FrameProvider;
|
|
||||||
} // namespace Lottie
|
} // namespace Lottie
|
||||||
|
|
||||||
namespace Main {
|
namespace Main {
|
||||||
|
@ -53,6 +52,8 @@ private:
|
||||||
not_null<const Element*> view;
|
not_null<const Element*> view;
|
||||||
std::unique_ptr<Lottie::SinglePlayer> lottie;
|
std::unique_ptr<Lottie::SinglePlayer> lottie;
|
||||||
QPoint shift;
|
QPoint shift;
|
||||||
|
QSize inner;
|
||||||
|
QSize outer;
|
||||||
int frame = 0;
|
int frame = 0;
|
||||||
int framesCount = 0;
|
int framesCount = 0;
|
||||||
int frameRate = 0;
|
int frameRate = 0;
|
||||||
|
@ -68,9 +69,7 @@ private:
|
||||||
bool incoming = false;
|
bool incoming = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] QRect computeRect(
|
[[nodiscard]] QRect computeRect(const Play &play) const;
|
||||||
not_null<const Element*> view,
|
|
||||||
bool premium) const;
|
|
||||||
|
|
||||||
void play(
|
void play(
|
||||||
QString emoticon,
|
QString emoticon,
|
||||||
|
@ -87,28 +86,16 @@ private:
|
||||||
bool premium);
|
bool premium);
|
||||||
void checkDelayed();
|
void checkDelayed();
|
||||||
|
|
||||||
[[nodiscard]] QSize sizeFor(bool premium) const;
|
|
||||||
[[nodiscard]] std::unique_ptr<Lottie::SinglePlayer> preparePlayer(
|
|
||||||
not_null<DocumentData*> document,
|
|
||||||
QByteArray data,
|
|
||||||
QString filepath,
|
|
||||||
bool premium);
|
|
||||||
|
|
||||||
const not_null<Main::Session*> _session;
|
const not_null<Main::Session*> _session;
|
||||||
const Fn<int(not_null<const Element*>)> _itemTop;
|
const Fn<int(not_null<const Element*>)> _itemTop;
|
||||||
|
|
||||||
int _visibleTop = 0;
|
int _visibleTop = 0;
|
||||||
int _visibleBottom = 0;
|
int _visibleBottom = 0;
|
||||||
QSize _emojiSize;
|
|
||||||
QSize _premiumSize;
|
|
||||||
|
|
||||||
std::vector<Play> _plays;
|
std::vector<Play> _plays;
|
||||||
std::vector<Delayed> _delayed;
|
std::vector<Delayed> _delayed;
|
||||||
rpl::event_stream<QRect> _updateRequests;
|
rpl::event_stream<QRect> _updateRequests;
|
||||||
rpl::event_stream<QString> _playStarted;
|
rpl::event_stream<QString> _playStarted;
|
||||||
base::flat_map<
|
|
||||||
not_null<DocumentData*>,
|
|
||||||
std::weak_ptr<Lottie::FrameProvider>> _sharedProviders;
|
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kMaxSizeFixed = 512;
|
constexpr auto kMaxSizeFixed = 512;
|
||||||
constexpr auto kMaxEmojiSizeFixed = 256;
|
constexpr auto kMaxEmojiSizeFixed = 256;
|
||||||
|
constexpr auto kPremiumMultiplier = 1.5;
|
||||||
|
constexpr auto kEmojiMultiplier = 3;
|
||||||
|
|
||||||
[[nodiscard]] QImage CacheDiceImage(
|
[[nodiscard]] QImage CacheDiceImage(
|
||||||
const QString &emoji,
|
const QString &emoji,
|
||||||
|
@ -104,12 +106,12 @@ bool Sticker::isEmojiSticker() const {
|
||||||
|
|
||||||
void Sticker::initSize() {
|
void Sticker::initSize() {
|
||||||
if (isEmojiSticker() || _diceIndex >= 0) {
|
if (isEmojiSticker() || _diceIndex >= 0) {
|
||||||
_size = Sticker::EmojiSize();
|
_size = EmojiSize();
|
||||||
if (_diceIndex > 0) {
|
if (_diceIndex > 0) {
|
||||||
[[maybe_unused]] bool result = readyToDrawLottie();
|
[[maybe_unused]] bool result = readyToDrawLottie();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_size = DownscaledSize(_data->dimensions, Sticker::Size());
|
_size = Size(_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +147,18 @@ QSize Sticker::Size() {
|
||||||
return { side, side };
|
return { side, side };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSize Sticker::Size(not_null<DocumentData*> document) {
|
||||||
|
return DownscaledSize(document->dimensions, Size());
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize Sticker::PremiumEffectSize(not_null<DocumentData*> document) {
|
||||||
|
return Size(document) * kPremiumMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize Sticker::EmojiEffectSize() {
|
||||||
|
return EmojiSize() * kEmojiMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
QSize Sticker::EmojiSize() {
|
QSize Sticker::EmojiSize() {
|
||||||
const auto side = std::min(st::maxAnimatedEmojiSize, kMaxEmojiSizeFixed);
|
const auto side = std::min(st::maxAnimatedEmojiSize, kMaxEmojiSizeFixed);
|
||||||
return { side, side };
|
return { side, side };
|
||||||
|
|
|
@ -77,6 +77,10 @@ public:
|
||||||
[[nodiscard]] bool readyToDrawLottie();
|
[[nodiscard]] bool readyToDrawLottie();
|
||||||
|
|
||||||
[[nodiscard]] static QSize Size();
|
[[nodiscard]] static QSize Size();
|
||||||
|
[[nodiscard]] static QSize Size(not_null<DocumentData*> document);
|
||||||
|
[[nodiscard]] static QSize PremiumEffectSize(
|
||||||
|
not_null<DocumentData*> document);
|
||||||
|
[[nodiscard]] static QSize EmojiEffectSize();
|
||||||
[[nodiscard]] static QSize EmojiSize();
|
[[nodiscard]] static QSize EmojiSize();
|
||||||
[[nodiscard]] static ClickHandlerPtr ShowSetHandler(
|
[[nodiscard]] static ClickHandlerPtr ShowSetHandler(
|
||||||
not_null<DocumentData*> document);
|
not_null<DocumentData*> document);
|
||||||
|
|
|
@ -7,12 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "window/window_media_preview.h"
|
#include "window/window_media_preview.h"
|
||||||
|
|
||||||
|
#include "chat_helpers/stickers_lottie.h"
|
||||||
|
#include "chat_helpers/stickers_emoji_pack.h"
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_photo_media.h"
|
#include "data/data_photo_media.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_document_media.h"
|
#include "data/data_document_media.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/stickers/data_stickers.h"
|
#include "data/stickers/data_stickers.h"
|
||||||
|
#include "history/view/media/history_view_sticker.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/emoji_config.h"
|
#include "ui/emoji_config.h"
|
||||||
#include "lottie/lottie_single_player.h"
|
#include "lottie/lottie_single_player.h"
|
||||||
|
@ -72,10 +75,10 @@ void MediaPreviewWidget::paintEvent(QPaintEvent *e) {
|
||||||
: Lottie::Animation::FrameInfo();
|
: Lottie::Animation::FrameInfo();
|
||||||
const auto image = frame.image;
|
const auto image = frame.image;
|
||||||
const auto effectImage = effect.image;
|
const auto effectImage = effect.image;
|
||||||
const auto framesCount = !image.isNull() ? _lottie->framesCount() : 1;
|
//const auto framesCount = !image.isNull() ? _lottie->framesCount() : 1;
|
||||||
const auto effectsCount = !effectImage.isNull()
|
//const auto effectsCount = !effectImage.isNull()
|
||||||
? _effect->framesCount()
|
// ? _effect->framesCount()
|
||||||
: 1;
|
// : 1;
|
||||||
const auto pixmap = image.isNull() ? currentImage() : QPixmap();
|
const auto pixmap = image.isNull() ? currentImage() : QPixmap();
|
||||||
const auto size = image.isNull() ? pixmap.size() : image.size();
|
const auto size = image.isNull() ? pixmap.size() : image.size();
|
||||||
int w = size.width() / factor, h = size.height() / factor;
|
int w = size.width() / factor, h = size.height() / factor;
|
||||||
|
@ -309,15 +312,25 @@ void MediaPreviewWidget::setupLottie() {
|
||||||
Expects(_document != nullptr);
|
Expects(_document != nullptr);
|
||||||
|
|
||||||
const auto factor = cIntRetinaFactor();
|
const auto factor = cIntRetinaFactor();
|
||||||
const auto size = currentDimensions();
|
|
||||||
_lottie = std::make_unique<Lottie::SinglePlayer>(
|
|
||||||
Lottie::ReadContent(_documentMedia->bytes(), _document->filepath()),
|
|
||||||
Lottie::FrameRequest{ size * factor },
|
|
||||||
Lottie::Quality::High);
|
|
||||||
if (_document->isPremiumSticker()) {
|
if (_document->isPremiumSticker()) {
|
||||||
_effect = std::make_unique<Lottie::SinglePlayer>(
|
const auto size = HistoryView::Sticker::Size(_document);
|
||||||
Lottie::ReadContent(_documentMedia->videoThumbnailContent(), {}),
|
_cachedSize = size;
|
||||||
Lottie::FrameRequest{ size * kPremiumMultiplier * factor },
|
_lottie = ChatHelpers::LottiePlayerFromDocument(
|
||||||
|
_documentMedia.get(),
|
||||||
|
nullptr,
|
||||||
|
ChatHelpers::StickerLottieSize::MessageHistory,
|
||||||
|
size * factor,
|
||||||
|
Lottie::Quality::High);
|
||||||
|
_effect = _document->session().emojiStickersPack().effectPlayer(
|
||||||
|
_document,
|
||||||
|
_documentMedia->videoThumbnailContent(),
|
||||||
|
QString(),
|
||||||
|
true);
|
||||||
|
} else {
|
||||||
|
const auto size = currentDimensions();
|
||||||
|
_lottie = std::make_unique<Lottie::SinglePlayer>(
|
||||||
|
Lottie::ReadContent(_documentMedia->bytes(), _document->filepath()),
|
||||||
|
Lottie::FrameRequest{ size * factor },
|
||||||
Lottie::Quality::High);
|
Lottie::Quality::High);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue