mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Proof-of-concept animated custom emoji.
This commit is contained in:
parent
21aa1323ec
commit
2e6733e433
9 changed files with 76 additions and 19 deletions
|
@ -249,7 +249,9 @@ std::unique_ptr<Ui::Text::CustomEmoji> UiIntegration::createCustomEmoji(
|
|||
if (!my || !my->session) {
|
||||
return nullptr;
|
||||
}
|
||||
return my->session->data().customEmojiManager().create(data);
|
||||
return my->session->data().customEmojiManager().create(
|
||||
data,
|
||||
my->customEmojiRepaint);
|
||||
}
|
||||
|
||||
rpl::producer<> UiIntegration::forcePopupMenuHideRequests() {
|
||||
|
|
|
@ -28,6 +28,7 @@ struct MarkedTextContext {
|
|||
|
||||
Main::Session *session = nullptr;
|
||||
HashtagMentionType type = HashtagMentionType::Telegram;
|
||||
Fn<void()> customEmojiRepaint;
|
||||
};
|
||||
|
||||
class UiIntegration final : public Ui::Integration {
|
||||
|
|
|
@ -11,6 +11,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "main/main_session.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_document_media.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "lottie/lottie_common.h"
|
||||
#include "lottie/lottie_single_player.h"
|
||||
#include "chat_helpers/stickers_lottie.h"
|
||||
#include "ui/text/text_block.h"
|
||||
|
||||
namespace Data {
|
||||
|
@ -72,40 +77,74 @@ class DocumentCustomEmoji final : public CustomEmojiWithData {
|
|||
public:
|
||||
DocumentCustomEmoji(
|
||||
const QString &data,
|
||||
not_null<DocumentData*> document);
|
||||
not_null<DocumentData*> document,
|
||||
Fn<void()> update);
|
||||
|
||||
void paint(QPainter &p, int x, int y) override;
|
||||
|
||||
private:
|
||||
not_null<DocumentData*> _document;
|
||||
std::shared_ptr<Data::DocumentMedia> _media;
|
||||
std::unique_ptr<Lottie::SinglePlayer> _lottie;
|
||||
Fn<void()> _update;
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
DocumentCustomEmoji::DocumentCustomEmoji(
|
||||
const QString &data,
|
||||
not_null<DocumentData*> document)
|
||||
not_null<DocumentData*> document,
|
||||
Fn<void()> update)
|
||||
: CustomEmojiWithData(data)
|
||||
, _document(document) {
|
||||
, _document(document)
|
||||
, _update(update) {
|
||||
}
|
||||
|
||||
void DocumentCustomEmoji::paint(QPainter &p, int x, int y) {
|
||||
const auto size = Ui::Emoji::GetSizeNormal() / style::DevicePixelRatio();
|
||||
p.fillRect(QRect{ x, y, size, size }, Qt::red);
|
||||
if (!_media) {
|
||||
_media = _document->createMediaView();
|
||||
_media->automaticLoad(_document->stickerSetOrigin(), nullptr);
|
||||
}
|
||||
if (_media->loaded() && !_lottie) {
|
||||
const auto size = Ui::Emoji::GetSizeNormal();
|
||||
_lottie = ChatHelpers::LottiePlayerFromDocument(
|
||||
_media.get(),
|
||||
nullptr,
|
||||
ChatHelpers::StickerLottieSize::MessageHistory,
|
||||
QSize(size, size),
|
||||
Lottie::Quality::High);
|
||||
_lottie->updates() | rpl::start_with_next(_update, _lifetime);
|
||||
}
|
||||
if (_lottie && _lottie->ready()) {
|
||||
const auto frame = _lottie->frame();
|
||||
p.drawImage(
|
||||
QRect(
|
||||
x,
|
||||
y,
|
||||
frame.width() / frame.devicePixelRatio(),
|
||||
frame.height() / frame.devicePixelRatio()),
|
||||
frame);
|
||||
_lottie->markFrameShown();
|
||||
}
|
||||
}
|
||||
|
||||
class ResolvingCustomEmoji final : public CustomEmojiWithData {
|
||||
public:
|
||||
explicit ResolvingCustomEmoji(const QString &data);
|
||||
ResolvingCustomEmoji(const QString &data, Fn<void()> update);
|
||||
|
||||
void paint(QPainter &p, int x, int y) override;
|
||||
|
||||
private:
|
||||
std::optional<DocumentCustomEmoji> _resolved;
|
||||
Fn<void()> _update;
|
||||
|
||||
};
|
||||
|
||||
ResolvingCustomEmoji::ResolvingCustomEmoji(const QString &data)
|
||||
: CustomEmojiWithData(data) {
|
||||
ResolvingCustomEmoji::ResolvingCustomEmoji(
|
||||
const QString &data,
|
||||
Fn<void()> update)
|
||||
: CustomEmojiWithData(data)
|
||||
, _update(update) {
|
||||
}
|
||||
|
||||
void ResolvingCustomEmoji::paint(QPainter &p, int x, int y) {
|
||||
|
@ -123,16 +162,17 @@ CustomEmojiManager::CustomEmojiManager(not_null<Session*> owner)
|
|||
CustomEmojiManager::~CustomEmojiManager() = default;
|
||||
|
||||
std::unique_ptr<Ui::Text::CustomEmoji> CustomEmojiManager::create(
|
||||
const QString &data) {
|
||||
const QString &data,
|
||||
Fn<void()> update) {
|
||||
const auto parsed = ParseCustomEmojiData(data);
|
||||
if (!parsed.id) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto document = _owner->document(parsed.id);
|
||||
if (!document->isNull()) {
|
||||
return std::make_unique<DocumentCustomEmoji>(data, document);
|
||||
return std::make_unique<DocumentCustomEmoji>(data, document, update);
|
||||
}
|
||||
return std::make_unique<ResolvingCustomEmoji>(data);
|
||||
return std::make_unique<ResolvingCustomEmoji>(data, update);
|
||||
}
|
||||
|
||||
Main::Session &CustomEmojiManager::session() const {
|
||||
|
|
|
@ -21,7 +21,8 @@ public:
|
|||
~CustomEmojiManager();
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Ui::Text::CustomEmoji> create(
|
||||
const QString &data);
|
||||
const QString &data,
|
||||
Fn<void()> update);
|
||||
|
||||
[[nodiscard]] Main::Session &session() const;
|
||||
[[nodiscard]] Session &owner() const;
|
||||
|
|
|
@ -1497,7 +1497,9 @@ void HistoryMessage::setText(const TextWithEntities &textWithEntities) {
|
|||
|
||||
clearIsolatedEmoji();
|
||||
const auto context = Core::MarkedTextContext{
|
||||
.session = &history()->session()
|
||||
.session = &history()->session(),
|
||||
.customEmojiRepaint = [=] {
|
||||
history()->owner().requestItemRepaint(this); },
|
||||
};
|
||||
_text.setMarkedText(
|
||||
st::messageTextStyle,
|
||||
|
|
|
@ -35,7 +35,9 @@ Game::Game(
|
|||
, _description(st::msgMinWidth - st::webPageLeft) {
|
||||
if (!consumed.text.isEmpty()) {
|
||||
const auto context = Core::MarkedTextContext{
|
||||
.session = &history()->session()
|
||||
.session = &history()->session(),
|
||||
.customEmojiRepaint = [=] {
|
||||
history()->owner().requestViewRepaint(_parent); },
|
||||
};
|
||||
_description.setMarkedText(
|
||||
st::webPageDescriptionStyle,
|
||||
|
@ -428,7 +430,9 @@ void Game::parentTextUpdated() {
|
|||
const auto consumed = media->consumedMessageText();
|
||||
if (!consumed.text.isEmpty()) {
|
||||
const auto context = Core::MarkedTextContext{
|
||||
.session = &history()->session()
|
||||
.session = &history()->session(),
|
||||
.customEmojiRepaint = [=] {
|
||||
history()->owner().requestViewRepaint(_parent); },
|
||||
};
|
||||
_description.setMarkedText(
|
||||
st::webPageDescriptionStyle,
|
||||
|
|
|
@ -200,7 +200,9 @@ Ui::Text::String Media::createCaption(not_null<HistoryItem*> item) const {
|
|||
- st::msgPadding.right();
|
||||
auto result = Ui::Text::String(minResizeWidth);
|
||||
const auto context = Core::MarkedTextContext{
|
||||
.session = &history()->session()
|
||||
.session = &history()->session(),
|
||||
.customEmojiRepaint = [=] {
|
||||
history()->owner().requestViewRepaint(_parent); },
|
||||
};
|
||||
result.setMarkedText(
|
||||
st::messageTextStyle,
|
||||
|
|
|
@ -210,7 +210,11 @@ QSize WebPage::countOptimalSize() {
|
|||
- st::msgPadding.right()
|
||||
- st::webPageLeft);
|
||||
}
|
||||
auto context = Core::MarkedTextContext();
|
||||
auto context = Core::MarkedTextContext{
|
||||
.session = &history()->session(),
|
||||
.customEmojiRepaint = [=] {
|
||||
history()->owner().requestViewRepaint(_parent); },
|
||||
};
|
||||
using MarkedTextContext = Core::MarkedTextContext;
|
||||
if (_data->siteName == qstr("Twitter")) {
|
||||
context.type = MarkedTextContext::HashtagMentionType::Twitter;
|
||||
|
|
|
@ -2265,7 +2265,8 @@ void OverlayWidget::refreshCaption() {
|
|||
? TimestampLinkBase(_document, _message->fullId())
|
||||
: QString();
|
||||
const auto context = Core::MarkedTextContext{
|
||||
.session = &_message->history()->session()
|
||||
.session = &_message->history()->session(),
|
||||
.customEmojiRepaint = [=] { update(); },
|
||||
};
|
||||
_caption.setMarkedText(
|
||||
st::mediaviewCaptionStyle,
|
||||
|
|
Loading…
Add table
Reference in a new issue