diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index c7652ae55a..1aaab01eba 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -226,6 +226,7 @@ void ShareBox::prepareCommentField() { _show, field, nullptr, + nullptr, _descriptor.stLabel); } field->setSubmitSettings(Core::App().settings().sendSubmitWay()); diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp index 6eaefea572..c2163c26ed 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp @@ -474,7 +474,7 @@ void EmojiListWidget::repaintLater( DocumentId documentId, uint64 setId, Ui::CustomEmoji::RepaintRequest request) { - if (_instances.empty()) { + if (_instances.empty() || !request.when) { return; } auto &repaint = _repaints[request.duration]; diff --git a/Telegram/SourceFiles/chat_helpers/message_field.cpp b/Telegram/SourceFiles/chat_helpers/message_field.cpp index 2c5ef8d7ac..9df0eaa4cf 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.cpp +++ b/Telegram/SourceFiles/chat_helpers/message_field.cpp @@ -54,23 +54,29 @@ constexpr auto kParseLinksTimeout = crl::time(1000); // ignore tags for different users. class FieldTagMimeProcessor final { public: - explicit FieldTagMimeProcessor(not_null _session); + FieldTagMimeProcessor( + not_null _session, + Fn)> unavailableEmojiPasted); QString operator()(QStringView mimeTag); private: const not_null _session; + const Fn)> _unavailableEmojiPasted; }; FieldTagMimeProcessor::FieldTagMimeProcessor( - not_null session) -: _session(session) { + not_null session, + Fn)> unavailableEmojiPasted) +: _session(session) +, _unavailableEmojiPasted(unavailableEmojiPasted) { } QString FieldTagMimeProcessor::operator()(QStringView mimeTag) { const auto id = _session->userId().bare; auto all = TextUtilities::SplitTags(mimeTag); + auto premiumSkipped = (DocumentData*)nullptr; for (auto i = all.begin(); i != all.end();) { const auto tag = *i; if (TextUtilities::IsMentionLink(tag) @@ -86,7 +92,8 @@ QString FieldTagMimeProcessor::operator()(QStringView mimeTag) { } if (!_session->premium()) { const auto document = _session->data().document(emoji.id); - if (document->isPremiumSticker()) { + if (document->isPremiumEmoji()) { + premiumSkipped = document; i = all.erase(i); continue; } @@ -94,6 +101,11 @@ QString FieldTagMimeProcessor::operator()(QStringView mimeTag) { } ++i; } + if (premiumSkipped + && _session->premiumPossible() + && _unavailableEmojiPasted) { + _unavailableEmojiPasted(premiumSkipped); + } return TextUtilities::JoinTag(all); } @@ -301,8 +313,10 @@ void InitMessageFieldHandlers( std::shared_ptr show, not_null field, Fn customEmojiPaused, + Fn)> unavailableEmojiPasted, const style::InputField *fieldStyle) { - field->setTagMimeProcessor(FieldTagMimeProcessor(session)); + field->setTagMimeProcessor( + FieldTagMimeProcessor(session, unavailableEmojiPasted)); field->setCustomEmojiFactory([=](QStringView data, Fn update) { return session->data().customEmojiManager().create( data, @@ -322,12 +336,14 @@ void InitMessageFieldHandlers( void InitMessageFieldHandlers( not_null controller, not_null field, - Window::GifPauseReason pauseReasonLevel) { + Window::GifPauseReason pauseReasonLevel, + Fn)> unavailableEmojiPasted) { InitMessageFieldHandlers( &controller->session(), std::make_shared(controller), field, - [=] { return controller->isGifPausedAtLeastFor(pauseReasonLevel); }); + [=] { return controller->isGifPausedAtLeastFor(pauseReasonLevel); }, + unavailableEmojiPasted); } void InitMessageFieldGeometry(not_null field) { @@ -341,8 +357,13 @@ void InitMessageFieldGeometry(not_null field) { void InitMessageField( not_null controller, - not_null field) { - InitMessageFieldHandlers(controller, field, Window::GifPauseReason::Any); + not_null field, + Fn)> unavailableEmojiPasted) { + InitMessageFieldHandlers( + controller, + field, + Window::GifPauseReason::Any, + unavailableEmojiPasted); InitMessageFieldGeometry(field); field->customTab(true); } diff --git a/Telegram/SourceFiles/chat_helpers/message_field.h b/Telegram/SourceFiles/chat_helpers/message_field.h index a5236ed8a0..0c0bbb8654 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.h +++ b/Telegram/SourceFiles/chat_helpers/message_field.h @@ -49,14 +49,17 @@ void InitMessageFieldHandlers( std::shared_ptr show, not_null field, Fn customEmojiPaused, + Fn)> unavailableEmojiPasted = nullptr, const style::InputField *fieldStyle = nullptr); void InitMessageFieldHandlers( not_null controller, not_null field, - Window::GifPauseReason pauseReasonLevel); + Window::GifPauseReason pauseReasonLevel, + Fn)> unavailableEmojiPasted = nullptr); void InitMessageField( not_null controller, - not_null field); + not_null field, + Fn)> unavailableEmojiPasted); void InitSpellchecker( std::shared_ptr show, diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index c24fb6d9f9..6bba223c3d 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -394,7 +394,10 @@ HistoryWidget::HistoryWidget( return _history ? _history->peer.get() : nullptr; }); - InitMessageField(controller, _field); + InitMessageField(controller, _field, [=]( + not_null document) { + showPremiumToast(document); + }); _keyboard->sendCommandRequests( ) | rpl::start_with_next([=](Bot::SendCommandRequest r) { @@ -6732,17 +6735,21 @@ void HistoryWidget::showPremiumStickerTooltip( not_null view) { if (const auto media = view->data()->media()) { if (const auto document = media->document()) { - if (!_stickerToast) { - _stickerToast = std::make_unique( - controller(), - _scroll.data(), - [=] { _stickerToast = nullptr; }); - } - _stickerToast->showFor(document); + showPremiumToast(document); } } } +void HistoryWidget::showPremiumToast(not_null document) { + if (!_stickerToast) { + _stickerToast = std::make_unique( + controller(), + _scroll.data(), + [=] { _stickerToast = nullptr; }); + } + _stickerToast->showFor(document); +} + void HistoryWidget::setFieldText( const TextWithTags &textWithTags, TextUpdateEvents events, diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 38aa438b08..f3fa55d36b 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -265,6 +265,7 @@ public: Fn hiddenCallback); void showPremiumStickerTooltip( not_null view); + void showPremiumToast(not_null document); // Tabbed selector management. bool pushTabbedSelectorToThirdSection( diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index a9c1653a55..5da0009d03 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -811,6 +811,7 @@ MessageToEdit FieldHeader::queryToEdit() { ComposeControls::ComposeControls( not_null parent, not_null window, + Fn)> unavailableEmojiPasted, Mode mode, SendMenu::Type sendMenuType) : _parent(parent) @@ -847,6 +848,7 @@ ComposeControls::ComposeControls( _send, st::historySendSize.height())) , _sendMenuType(sendMenuType) +, _unavailableEmojiPasted(unavailableEmojiPasted) , _saveDraftTimer([=] { saveDraft(); }) { init(); } @@ -1420,7 +1422,7 @@ void ComposeControls::initField() { Ui::Connect(_field, &Ui::InputField::resized, [=] { updateHeight(); }); //Ui::Connect(_field, &Ui::InputField::focused, [=] { fieldFocused(); }); Ui::Connect(_field, &Ui::InputField::changed, [=] { fieldChanged(); }); - InitMessageField(_window, _field); + InitMessageField(_window, _field, _unavailableEmojiPasted); initAutocomplete(); const auto suggestions = Ui::Emoji::SuggestionsController::Init( _parent, @@ -1963,7 +1965,7 @@ void ComposeControls::initVoiceRecordBar() { _voiceRecordBar->setStartRecordingFilter([=] { const auto error = [&]() -> std::optional { - const auto peer = _history ? _history->peer : nullptr; + const auto peer = _history ? _history->peer.get() : nullptr; if (!peer) { const auto type = ChatRestriction::SendMedia; if (const auto error = Data::RestrictionError(peer, type)) { diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h index 87458c08b0..ab5947546b 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h @@ -97,6 +97,7 @@ public: ComposeControls( not_null parent, not_null window, + Fn)> unavailableEmojiPasted, Mode mode, SendMenu::Type sendMenuType); ~ComposeControls(); @@ -309,6 +310,7 @@ private: const std::unique_ptr _voiceRecordBar; const SendMenu::Type _sendMenuType; + const Fn)> _unavailableEmojiPasted; rpl::event_stream _sendCustomRequests; rpl::event_stream<> _cancelRequests; diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 02b411b7a1..bc32e3f75d 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -1494,6 +1494,12 @@ void ListWidget::elementStartPremium( not_null view, Element *replacing) { _emojiInteractions->playPremiumEffect(view, replacing); + const auto already = !_emojiInteractions->playPremiumEffect( + view, + replacing); + if (already) { + showPremiumStickerTooltip(view); + } } void ListWidget::elementCancelPremium(not_null view) { @@ -1599,6 +1605,15 @@ void ListWidget::startMessageSendingAnimation( }); } +void ListWidget::showPremiumStickerTooltip( + not_null view) { + if (const auto media = view->data()->media()) { + if (const auto document = media->document()) { + _delegate->listShowPremiumToast(document); + } + } +} + void ListWidget::revealItemsCallback() { auto revealHeight = 0; for (auto i = begin(_itemRevealAnimations) diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.h b/Telegram/SourceFiles/history/view/history_view_list_widget.h index 2233f8e5c2..f83d3c004c 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.h +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.h @@ -119,6 +119,7 @@ public: virtual CopyRestrictionType listSelectRestrictionType() = 0; virtual auto listAllowedReactionsValue() -> rpl::producer>> = 0; + virtual void listShowPremiumToast(not_null document) = 0; }; struct SelectionData { @@ -516,6 +517,8 @@ private: void revealItemsCallback(); void startMessageSendingAnimation(not_null item); + void showPremiumStickerTooltip( + not_null view); // This function finds all history items that are displayed and calls template method // for each found message (in given direction) in the passed history with passed top offset. diff --git a/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp b/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp index 38b69af643..5ca94f632f 100644 --- a/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp @@ -688,6 +688,9 @@ auto PinnedWidget::listAllowedReactionsValue() return Data::PeerAllowedReactionsValue(_history->peer); } +void PinnedWidget::listShowPremiumToast(not_null document) { +} + void PinnedWidget::confirmDeleteSelected() { ConfirmDeleteSelectedItems(_inner); } diff --git a/Telegram/SourceFiles/history/view/history_view_pinned_section.h b/Telegram/SourceFiles/history/view/history_view_pinned_section.h index 0383b190a0..518ceadc29 100644 --- a/Telegram/SourceFiles/history/view/history_view_pinned_section.h +++ b/Telegram/SourceFiles/history/view/history_view_pinned_section.h @@ -107,6 +107,7 @@ public: CopyRestrictionType listSelectRestrictionType() override; auto listAllowedReactionsValue() -> rpl::producer>> override; + void listShowPremiumToast(not_null document) override; protected: void resizeEvent(QResizeEvent *e) override; diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 3ecbe5fc4e..4e5cc64be7 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_list_widget.h" #include "history/view/history_view_schedule_box.h" #include "history/view/history_view_pinned_bar.h" +#include "history/view/history_view_sticker_toast.h" #include "history/history.h" #include "history/history_drag_area.h" #include "history/history_item_components.h" @@ -165,6 +166,7 @@ RepliesWidget::RepliesWidget( , _composeControls(std::make_unique( this, controller, + [=](not_null emoji) { listShowPremiumToast(emoji); }, ComposeControls::Mode::Normal, SendMenu::Type::SilentOnly)) , _scroll(std::make_unique( @@ -2043,6 +2045,16 @@ auto RepliesWidget::listAllowedReactionsValue() return Data::PeerAllowedReactionsValue(_history->peer); } +void RepliesWidget::listShowPremiumToast(not_null document) { + if (!_stickerToast) { + _stickerToast = std::make_unique( + controller(), + _scroll.get(), + [=] { _stickerToast = nullptr; }); + } + _stickerToast->showFor(document); +} + void RepliesWidget::confirmDeleteSelected() { ConfirmDeleteSelectedItems(_inner); } diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.h b/Telegram/SourceFiles/history/view/history_view_replies_section.h index eccf68a5c2..31296bce5f 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.h +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.h @@ -62,6 +62,7 @@ class TopBarWidget; class RepliesMemento; class ComposeControls; class SendActionPainter; +class StickerToast; class RepliesWidget final : public Window::SectionWidget @@ -143,6 +144,7 @@ public: CopyRestrictionType listSelectRestrictionType() override; auto listAllowedReactionsValue() -> rpl::producer>> override; + void listShowPremiumToast(not_null document) override; protected: void resizeEvent(QResizeEvent *e) override; @@ -193,6 +195,8 @@ private: void clearSelected(); void setPinnedVisibility(bool shown); + void showPremiumToast(not_null document); + [[nodiscard]] Api::SendAction prepareSendAction( Api::SendOptions options) const; void send(); @@ -284,6 +288,7 @@ private: rpl::variable _rootVisible = false; std::unique_ptr _scroll; + std::unique_ptr _stickerToast; std::vector _replyReturns; HistoryItem *_replyReturn = nullptr; diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index 957a2cebfe..264ad9b5cf 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_top_bar_widget.h" #include "history/view/history_view_list_widget.h" #include "history/view/history_view_schedule_box.h" +#include "history/view/history_view_sticker_toast.h" #include "history/history.h" #include "history/history_drag_area.h" #include "history/history_item.h" @@ -107,6 +108,7 @@ ScheduledWidget::ScheduledWidget( , _composeControls(std::make_unique( this, controller, + [=](not_null emoji) { listShowPremiumToast(emoji); }, ComposeControls::Mode::Scheduled, SendMenu::Type::Disabled)) , _scrollDown( @@ -1360,6 +1362,17 @@ auto ScheduledWidget::listAllowedReactionsValue() return rpl::single(std::optional>(empty)); } +void ScheduledWidget::listShowPremiumToast( + not_null document) { + if (!_stickerToast) { + _stickerToast = std::make_unique( + controller(), + _scroll.data(), + [=] { _stickerToast = nullptr; }); + } + _stickerToast->showFor(document); +} + void ScheduledWidget::confirmSendNowSelected() { ConfirmSendNowSelectedItems(_inner); } diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h index 352924dc40..e8f6b543b2 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h @@ -48,6 +48,7 @@ class Element; class TopBarWidget; class ScheduledMemento; class ComposeControls; +class StickerToast; class ScheduledWidget final : public Window::SectionWidget @@ -128,6 +129,7 @@ public: CopyRestrictionType listSelectRestrictionType() override; auto listAllowedReactionsValue() -> rpl::producer>> override; + void listShowPremiumToast(not_null document) override; protected: void resizeEvent(QResizeEvent *e) override; @@ -236,6 +238,8 @@ private: std::unique_ptr _composeControls; bool _skipScrollEvent = false; + std::unique_ptr _stickerToast; + std::vector _replyReturns; HistoryItem *_replyReturn = nullptr; diff --git a/Telegram/SourceFiles/history/view/history_view_sticker_toast.cpp b/Telegram/SourceFiles/history/view/history_view_sticker_toast.cpp index c93b01d9c0..dbaad026a6 100644 --- a/Telegram/SourceFiles/history/view/history_view_sticker_toast.cpp +++ b/Telegram/SourceFiles/history/view/history_view_sticker_toast.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/toast/toast.h" #include "ui/toast/toast_widget.h" #include "ui/widgets/buttons.h" +#include "data/stickers/data_custom_emoji.h" #include "data/data_document.h" #include "data/data_document_media.h" #include "data/data_session.h" @@ -44,9 +45,7 @@ StickerToast::~StickerToast() { void StickerToast::showFor(not_null document) { const auto sticker = document->sticker(); - if (!sticker - || sticker->type != StickerType::Tgs - || !document->session().premiumPossible()) { + if (!sticker || !document->session().premiumPossible()) { return; } else if (const auto strong = _weak.get()) { if (_for == document) { @@ -121,10 +120,14 @@ void StickerToast::cancelRequest() { void StickerToast::showWithTitle(const QString &title) { Expects(_for != nullptr); + const auto setType = _for->sticker()->setType; + const auto isEmoji = (setType == Data::StickersType::Emoji); const auto text = Ui::Text::Bold( title ).append('\n').append( - tr::lng_sticker_premium_text(tr::now) + (isEmoji + ? tr::lng_animated_emoji_text(tr::now, Ui::Text::RichLangValue) + : tr::lng_sticker_premium_text(tr::now, Ui::Text::RichLangValue)) ); _st = st::historyPremiumToast; const auto skip = _st.padding.top(); @@ -167,28 +170,11 @@ void StickerToast::showWithTitle(const QString &title) { preview->resize(size, size); preview->show(); - const auto bytes = _for->createMediaView()->bytes(); - const auto filepath = _for->filepath(); - const auto player = preview->lifetime().make_state( - Lottie::ReadContent(bytes, filepath), - Lottie::FrameRequest{ QSize(size, size) }, - Lottie::Quality::Default); - preview->paintRequest( - ) | rpl::start_with_next([=] { - if (!player->ready()) { - return; - } - const auto image = player->frame(); - QPainter(preview).drawImage( - QRect(QPoint(), image.size() / image.devicePixelRatio()), - image); - player->markFrameShown(); - }, preview->lifetime()); - player->updates( - ) | rpl::start_with_next([=] { - preview->update(); - }, preview->lifetime()); - + if (isEmoji) { + setupEmojiPreview(preview, size); + } else { + setupLottiePreview(preview, size); + } button->setClickedCallback([=, weak = _weak] { _controller->show( Box(_controller, _for->sticker()->set), @@ -199,4 +185,95 @@ void StickerToast::showWithTitle(const QString &title) { }); } +void StickerToast::setupEmojiPreview( + not_null widget, + int size) { + Expects(_for != nullptr); + + struct Instance { + Instance( + std::unique_ptr loader, + Fn, + Ui::CustomEmoji::RepaintRequest)> repaintLater, + Fn repaint) + : emoji( + Ui::CustomEmoji::Loading( + std::move(loader), + Ui::CustomEmoji::Preview()), + std::move(repaintLater)) + , object(&emoji, repaint) + , timer(repaint) { + } + + Ui::CustomEmoji::Instance emoji; + Ui::CustomEmoji::Object object; + base::Timer timer; + }; + + const auto repaintDelayed = [=]( + not_null instance, + Ui::CustomEmoji::RepaintRequest request) { + if (!request.when) { + return; + } + const auto now = crl::now(); + if (now > request.when) { + reinterpret_cast(instance.get())->timer.callOnce( + now - request.when); + } else { + widget->update(); + } + }; + const auto instance = widget->lifetime().make_state( + _for->owner().customEmojiManager().createLoader( + _for, + Data::CustomEmojiManager::SizeTag::Large), + std::move(repaintDelayed), + [=] { widget->update(); }); + + widget->paintRequest( + ) | rpl::start_with_next([=] { + auto p = QPainter(widget); + const auto paused = false; + const auto size = Ui::Emoji::GetSizeLarge() + / style::DevicePixelRatio(); + instance->object.paint( + p, + (widget->width() - size) / 2, + (widget->height() - size) / 2, + crl::now(), + st::toastBg->c, + paused); + }, widget->lifetime()); +} + +void StickerToast::setupLottiePreview(not_null widget, int size) { + Expects(_for != nullptr); + + const auto bytes = _for->createMediaView()->bytes(); + const auto filepath = _for->filepath(); + const auto player = widget->lifetime().make_state( + Lottie::ReadContent(bytes, filepath), + Lottie::FrameRequest{ QSize(size, size) }, + Lottie::Quality::Default); + + widget->paintRequest( + ) | rpl::start_with_next([=] { + if (!player->ready()) { + return; + } + const auto image = player->frame(); + QPainter(widget).drawImage( + QRect(QPoint(), image.size() / image.devicePixelRatio()), + image); + player->markFrameShown(); + }, widget->lifetime()); + + player->updates( + ) | rpl::start_with_next([=] { + widget->update(); + }, widget->lifetime()); +} + } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/history_view_sticker_toast.h b/Telegram/SourceFiles/history/view/history_view_sticker_toast.h index d66e728af4..21d8d89971 100644 --- a/Telegram/SourceFiles/history/view/history_view_sticker_toast.h +++ b/Telegram/SourceFiles/history/view/history_view_sticker_toast.h @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { class Show; +class RpWidget; } // namespace Ui namespace Ui::Toast { @@ -39,6 +40,9 @@ private: void showWithTitle(const QString &title); [[nodiscard]] QString lookupTitle() const; + void setupEmojiPreview(not_null widget, int size); + void setupLottiePreview(not_null widget, int size); + const not_null _controller; const not_null _parent; style::Toast _st; diff --git a/Telegram/SourceFiles/storage/serialize_document.cpp b/Telegram/SourceFiles/storage/serialize_document.cpp index 434c304073..cd010c847b 100644 --- a/Telegram/SourceFiles/storage/serialize_document.cpp +++ b/Telegram/SourceFiles/storage/serialize_document.cpp @@ -60,7 +60,9 @@ void Document::writeToStream(QDataStream &stream, DocumentData *document) { } stream << qint32(document->getDuration()); if (document->type == StickerDocument) { - stream << qint32(document->isPremiumSticker() ? 1 : 0); + const auto premium = document->isPremiumSticker() + || document->isPremiumEmoji(); + stream << qint32(premium ? 1 : 0); } writeImageLocation(stream, document->thumbnailLocation()); stream << qint32(document->thumbnailByteSize());