diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index c099b7e20..93be919ea 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -376,8 +376,8 @@ void HistoryItem::invalidateChatListEntry() { } void HistoryItem::customEmojiRepaint() { - if (!_textRepaintScheduled) { - _textRepaintScheduled = true; + if (!_customEmojiRepaintScheduled) { + _customEmojiRepaintScheduled = true; history()->owner().requestItemRepaint(this); } } diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 658400f4a..0fb8d59cf 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -474,7 +474,7 @@ protected: Ui::Text::String _text = { st::msgMinWidth }; int _textWidth = -1; int _textHeight = 0; - bool _textRepaintScheduled = false; + bool _customEmojiRepaintScheduled = false; struct SavedMediaData { TextWithEntities text; diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 3bec4519f..c0d669367 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -42,8 +42,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_chat.h" #include "styles/style_window.h" -#include "data/stickers/data_custom_emoji.h" - namespace { [[nodiscard]] MessageFlags NewForwardedFlags( diff --git a/Telegram/SourceFiles/history/history_service.cpp b/Telegram/SourceFiles/history/history_service.cpp index d4fdbbf16..92bde18e0 100644 --- a/Telegram/SourceFiles/history/history_service.cpp +++ b/Telegram/SourceFiles/history/history_service.cpp @@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_group_call.h" // Data::GroupCall::id(). #include "core/application.h" #include "core/click_handler_types.h" +#include "core/ui_integration.h" #include "base/unixtime.h" #include "base/timer_rpl.h" #include "calls/calls_instance.h" // Core::App().calls().joinGroupCall. @@ -925,7 +926,12 @@ HistoryService::PreparedText HistoryService::preparePinnedText() { original = Ui::Text::Wrapped( Ui::Text::Filtered( std::move(original), - { EntityType::Spoiler, EntityType::StrikeOut }), + { + EntityType::Spoiler, + EntityType::StrikeOut, + EntityType::Italic, + EntityType::CustomEmoji, + }), EntityType::CustomUrl, Ui::Text::Link({}, 2).entities.front().data()); result.text = tr::lng_action_pinned_message( @@ -1251,10 +1257,15 @@ ClickHandlerPtr HistoryService::fromLink() const { } void HistoryService::setServiceText(const PreparedText &prepared) { + const auto context = Core::MarkedTextContext{ + .session = &history()->session(), + .customEmojiRepaint = [=] { customEmojiRepaint(); }, + }; _text.setMarkedText( st::serviceTextStyle, prepared.text, - Ui::ItemTextServiceOptions()); + Ui::ItemTextServiceOptions(), + context); HistoryView::FillTextWithAnimatedSpoilers(_text); auto linkIndex = 0; for (const auto &link : prepared.links) { diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 7e5f4ae79..501d895e4 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -413,6 +413,26 @@ void Element::refreshDataIdHook() { } void Element::customEmojiRepaint() { + if (!_customEmojiRepaintScheduled) { + _customEmojiRepaintScheduled = true; + history()->owner().requestViewRepaint(this); + } +} + +void Element::prepareCustomEmojiPaint( + Painter &p, + const Ui::Text::String &text) const { + const auto item = data(); + if (!text.hasCustomEmoji()) { + return; + } + _customEmojiRepaintScheduled = false; + item->_customEmojiRepaintScheduled = false; + p.setInactive(delegate()->elementIsGifPaused()); + if (!_heavyCustomEmoji) { + _heavyCustomEmoji = true; + history()->owner().registerHeavyViewPart(const_cast(this)); + } } //void Element::externalLottieProgressing(bool external) const { @@ -900,7 +920,7 @@ auto Element::verticalRepaintRange() const -> VerticalRepaintRange { } bool Element::hasHeavyPart() const { - return false; + return _heavyCustomEmoji; } void Element::checkHeavyPart() { @@ -921,6 +941,10 @@ void Element::unloadHeavyPart() { if (_media) { _media->unloadHeavyPart(); } + if (_heavyCustomEmoji) { + _heavyCustomEmoji = false; + data()->_text.unloadCustomEmoji(); + } } HistoryBlock *Element::block() { @@ -1094,6 +1118,11 @@ auto Element::takeReactionAnimations() Element::~Element() { // Delete media while owner still exists. base::take(_media); + if (_heavyCustomEmoji) { + _heavyCustomEmoji = false; + data()->_text.unloadCustomEmoji(); + checkHeavyPart(); + } if (_data->mainView() == this) { _data->clearMainView(); } diff --git a/Telegram/SourceFiles/history/view/history_view_element.h b/Telegram/SourceFiles/history/view/history_view_element.h index c21cf218f..975280bb6 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.h +++ b/Telegram/SourceFiles/history/view/history_view_element.h @@ -427,7 +427,10 @@ public: virtual QRect innerGeometry() const = 0; - virtual void customEmojiRepaint(); + void customEmojiRepaint(); + void prepareCustomEmojiPaint( + Painter &p, + const Ui::Text::String &text) const; [[nodiscard]] ClickHandlerPtr fromPhotoLink() const { return fromLink(); @@ -491,6 +494,9 @@ private: std::unique_ptr _media; mutable ClickHandlerPtr _fromLink; bool _isScheduledUntilOnline = false; + mutable bool _heavyCustomEmoji = false; + mutable bool _customEmojiRepaintScheduled = false; + const QDateTime _dateTime; int _y = 0; diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index b828f63f2..1438480e8 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -275,12 +275,8 @@ Message::Message( } Message::~Message() { - if (_comments || _heavyCustomEmoji) { + if (_comments) { _comments = nullptr; - if (_heavyCustomEmoji) { - _heavyCustomEmoji = false; - message()->_text.unloadCustomEmoji(); - } checkHeavyPart(); } } @@ -849,7 +845,6 @@ void Message::draw(Painter &p, const PaintContext &context) const { auto mediaPosition = QPoint( inner.left(), trect.y() + trect.height() - mediaHeight); - _mediaRepaintScheduled = false; p.translate(mediaPosition); media->draw(p, context.translated( -mediaPosition @@ -918,7 +913,6 @@ void Message::draw(Painter &p, const PaintContext &context) const { media->paintBubbleFireworks(p, g, context.now); } } else if (media && media->isDisplayed()) { - _mediaRepaintScheduled = false; p.translate(g.topLeft()); media->draw(p, context.translated( -g.topLeft() @@ -1246,10 +1240,7 @@ void Message::paintText( const auto stm = context.messageStyle(); p.setPen(stm->historyTextFg); p.setFont(st::msgFont); - const auto custom = item->_text.hasCustomEmoji(); - if (custom) { - p.setInactive(delegate()->elementIsGifPaused()); - } + prepareCustomEmojiPaint(p, item->_text); item->_text.draw( p, trect.x(), @@ -1259,11 +1250,6 @@ void Message::paintText( 0, -1, context.selection); - item->_textRepaintScheduled = false; - if (!_heavyCustomEmoji && custom) { - _heavyCustomEmoji = true; - history()->owner().registerHeavyViewPart(const_cast(this)); - } } PointState Message::pointState(QPoint point) const { @@ -1390,16 +1376,12 @@ void Message::toggleCommentsButtonRipple(bool pressed) { } bool Message::hasHeavyPart() const { - return _heavyCustomEmoji || _comments || Element::hasHeavyPart(); + return _comments || Element::hasHeavyPart(); } void Message::unloadHeavyPart() { Element::unloadHeavyPart(); _comments = nullptr; - if (_heavyCustomEmoji) { - _heavyCustomEmoji = false; - message()->_text.unloadCustomEmoji(); - } } bool Message::showForwardsFromSender( @@ -2824,13 +2806,6 @@ QRect Message::innerGeometry() const { return result; } -void Message::customEmojiRepaint() { - if (!_mediaRepaintScheduled) { - _mediaRepaintScheduled = true; - history()->owner().requestViewRepaint(this); - } -} - QRect Message::countGeometry() const { const auto commentsRoot = (context() == Context::Replies) && data()->isDiscussionPost(); diff --git a/Telegram/SourceFiles/history/view/history_view_message.h b/Telegram/SourceFiles/history/view/history_view_message.h index 151d7db90..1bbf929d2 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.h +++ b/Telegram/SourceFiles/history/view/history_view_message.h @@ -140,8 +140,6 @@ public: QRect innerGeometry() const override; - void customEmojiRepaint() override; - protected: void refreshDataIdHook() override; @@ -254,8 +252,6 @@ private: Ui::Text::String _rightBadge; int _bubbleWidthLimit = 0; - mutable bool _heavyCustomEmoji = false; - mutable bool _mediaRepaintScheduled = false; BottomInfo _bottomInfo; diff --git a/Telegram/SourceFiles/history/view/history_view_service_message.cpp b/Telegram/SourceFiles/history/view/history_view_service_message.cpp index 13fad925d..42e02fd4a 100644 --- a/Telegram/SourceFiles/history/view/history_view_service_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_service_message.cpp @@ -541,6 +541,7 @@ void Service::draw(Painter &p, const PaintContext &context) const { p.setBrush(Qt::NoBrush); p.setPen(st->msgServiceFg()); p.setFont(st::msgServiceFont); + prepareCustomEmojiPaint(p, item->_text); item->_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignCenter, 0, -1, context.selection, false); p.restoreTextPalette(); diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index 80488b93a..3d6e9a875 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -672,7 +672,7 @@ void Document::draw( } if (const auto captioned = Get()) { p.setPen(stm->historyTextFg); - applyCustomEmojiPause(p, captioned->_caption); + _parent->prepareCustomEmojiPaint(p, captioned->_caption); captioned->_caption.draw(p, st::msgPadding.left(), captiontop, captionw, style::al_left, 0, -1, selection); } } @@ -683,6 +683,9 @@ bool Document::hasHeavyPart() const { void Document::unloadHeavyPart() { _dataMedia = nullptr; + if (const auto captioned = Get()) { + captioned->_caption.unloadCustomEmoji(); + } } void Document::ensureDataMediaCreated() const { diff --git a/Telegram/SourceFiles/history/view/media/history_view_game.cpp b/Telegram/SourceFiles/history/view/media/history_view_game.cpp index c83f14fb3..859ca1961 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_game.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_game.cpp @@ -245,7 +245,7 @@ void Game::draw(Painter &p, const PaintContext &context) const { if (_description.hasSkipBlock()) { endskip = _parent->skipBlockWidth(); } - applyCustomEmojiPause(p, _description); + _parent->prepareCustomEmojiPaint(p, _description); _description.drawLeftElided(p, padding.left(), tshift, paintw, width(), _descriptionLines, style::al_left, 0, -1, endskip, false, toDescriptionSelection(context.selection)); tshift += _descriptionLines * lineHeight; } @@ -445,6 +445,17 @@ void Game::parentTextUpdated() { } } +bool Game::hasHeavyPart() const { + return _attach ? _attach->hasHeavyPart() : false; +} + +void Game::unloadHeavyPart() { + if (_attach) { + _attach->unloadHeavyPart(); + } + _description.unloadCustomEmoji(); +} + Game::~Game() { history()->owner().unregisterGameView(_data, _parent); } diff --git a/Telegram/SourceFiles/history/view/media/history_view_game.h b/Telegram/SourceFiles/history/view/media/history_view_game.h index 8bc94238a..062418569 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_game.h +++ b/Telegram/SourceFiles/history/view/media/history_view_game.h @@ -80,14 +80,8 @@ public: void parentTextUpdated() override; - bool hasHeavyPart() const override { - return _attach ? _attach->hasHeavyPart() : false; - } - void unloadHeavyPart() override { - if (_attach) { - _attach->unloadHeavyPart(); - } - } + bool hasHeavyPart() const override; + void unloadHeavyPart() override; ~Game(); diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp index 0c332cb16..17e9552db 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp @@ -670,7 +670,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const { } if (!unwrapped && !_caption.isEmpty()) { p.setPen(stm->historyTextFg); - applyCustomEmojiPause(p, _caption); + _parent->prepareCustomEmojiPaint(p, _caption); _caption.draw(p, st::msgPadding.left(), painty + painth + st::mediaCaptionSkip, captionw, style::al_left, 0, -1, context.selection); } else if (!inWebPage && !skipDrawingSurrounding) { auto fullRight = paintx + usex + usew; @@ -1471,6 +1471,7 @@ void Gif::unloadHeavyPart() { stopAnimation(); _dataMedia = nullptr; _videoThumbnailFrame = nullptr; + _caption.unloadCustomEmoji(); } void Gif::refreshParentId(not_null realParent) { diff --git a/Telegram/SourceFiles/history/view/media/history_view_media.cpp b/Telegram/SourceFiles/history/view/media/history_view_media.cpp index bfb06c5cd..ef477d482 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media.cpp @@ -191,14 +191,6 @@ void Media::repaint() const { history()->owner().requestViewRepaint(_parent); } -void Media::applyCustomEmojiPause( - Painter &p, - const Ui::Text::String &text) const { - if (text.hasCustomEmoji()) { - p.setInactive(_parent->delegate()->elementIsGifPaused()); - } -} - Ui::Text::String Media::createCaption(not_null item) const { if (item->emptyText()) { return {}; diff --git a/Telegram/SourceFiles/history/view/media/history_view_media.h b/Telegram/SourceFiles/history/view/media/history_view_media.h index 0dfbc8058..ef97df565 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media.h @@ -329,9 +329,6 @@ protected: [[nodiscard]] bool usesBubblePattern(const PaintContext &context) const; void repaint() const; - void applyCustomEmojiPause( - Painter &p, - const Ui::Text::String &text) const; const not_null _parent; MediaInBubbleState _inBubbleState = MediaInBubbleState::None; diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp index 3947c3815..22f0173a0 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp @@ -344,7 +344,7 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const { - _caption.countHeight(captionw); const auto stm = context.messageStyle(); p.setPen(stm->historyTextFg); - applyCustomEmojiPause(p, _caption); + _parent->prepareCustomEmojiPaint(p, _caption); _caption.draw(p, st::msgPadding.left(), captiony, captionw, style::al_left, 0, -1, selection); } else if (_parent->media() == this) { auto fullRight = width(); @@ -721,6 +721,7 @@ void GroupedMedia::unloadHeavyPart() { part.cacheKey = 0; part.cache = QPixmap(); } + _caption.unloadCustomEmoji(); } void GroupedMedia::parentTextUpdated() { diff --git a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp index 12d2d9e19..2a1e1eff9 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp @@ -133,6 +133,7 @@ bool Photo::hasHeavyPart() const { void Photo::unloadHeavyPart() { stopAnimation(); _dataMedia = nullptr; + _caption.unloadCustomEmoji(); } QSize Photo::countOptimalSize() { @@ -335,7 +336,7 @@ void Photo::draw(Painter &p, const PaintContext &context) const { // date if (!_caption.isEmpty()) { p.setPen(stm->historyTextFg); - applyCustomEmojiPause(p, _caption); + _parent->prepareCustomEmojiPaint(p, _caption); _caption.draw(p, st::msgPadding.left(), painty + painth + st::mediaCaptionSkip, captionw, style::al_left, 0, -1, context.selection); } else if (!inWebPage) { auto fullRight = paintx + paintw; diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp index 89c020e13..af991bfb9 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp @@ -464,6 +464,7 @@ void WebPage::unloadHeavyPart() { if (_attach) { _attach->unloadHeavyPart(); } + _description.unloadCustomEmoji(); _photoMedia = nullptr; } @@ -565,7 +566,7 @@ void WebPage::draw(Painter &p, const PaintContext &context) const { if (_description.hasSkipBlock()) { endskip = _parent->skipBlockWidth(); } - applyCustomEmojiPause(p, _description); + _parent->prepareCustomEmojiPaint(p, _description); if (_descriptionLines > 0) { _description.drawLeftElided(p, padding.left(), tshift, paintw, width(), _descriptionLines, style::al_left, 0, -1, endskip, false, toDescriptionSelection(context.selection)); tshift += _descriptionLines * lineHeight; diff --git a/Telegram/SourceFiles/ui/text/text_options.cpp b/Telegram/SourceFiles/ui/text/text_options.cpp index 36fd91b72..b2aa2fb50 100644 --- a/Telegram/SourceFiles/ui/text/text_options.cpp +++ b/Telegram/SourceFiles/ui/text/text_options.cpp @@ -40,7 +40,8 @@ TextParseOptions HistoryServiceOptions = { TextParseLinks | TextParseMentions //| TextParseMultiline - | TextParseHashtags, // flags + | TextParseHashtags + | TextParseMarkdown, // flags 0, // maxw 0, // maxh Qt::LayoutDirectionAuto, // lang-dependent