diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 0fb8d59cf..7ff9bbb31 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -431,6 +431,7 @@ public: void updateDate(TimeId newDate); [[nodiscard]] bool canUpdateDate() const; + void customEmojiRepaint(); [[nodiscard]] TimeId ttlDestroyAt() const { return _ttlDestroyAt; @@ -463,7 +464,6 @@ protected: MessageFlags _flags = 0; void invalidateChatListEntry(); - void customEmojiRepaint(); void setGroupId(MessageGroupId groupId); diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index 379fd7ffc..8379c4878 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_service_message.h" #include "history/view/media/history_view_document.h" #include "core/click_handler_types.h" +#include "core/ui_integration.h" #include "layout/layout_position.h" #include "mainwindow.h" #include "media/audio/media_audio.h" @@ -256,10 +257,15 @@ bool HistoryMessageReply::updateData( } if (replyToMsg) { + const auto context = Core::MarkedTextContext{ + .session = &holder->history()->session(), + .customEmojiRepaint = [=] { holder->customEmojiRepaint(); }, + }; replyToText.setMarkedText( st::messageTextStyle, replyToMsg->inReplyText(), - Ui::DialogTextOptions()); + Ui::DialogTextOptions(), + context); updateName(holder); @@ -447,6 +453,7 @@ void HistoryMessageReply::paint( p.setTextPalette(inBubble ? stm->replyTextPalette : st->imgReplyTextPalette()); + holder->prepareCustomEmojiPaint(p, replyToText); replyToText.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top() + st::msgServiceNameFont->height, w - st::msgReplyBarSkip - previewSkip, w + 2 * x); p.setTextPalette(stm->textPalette); } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 271c35d40..58d1f911b 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -149,6 +149,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "chat_helpers/emoji_suggestions_widget.h" #include "core/crash_reports.h" #include "core/shortcuts.h" +#include "core/ui_integration.h" #include "support/support_common.h" #include "support/support_autocomplete.h" #include "support/support_preload.h" @@ -6365,10 +6366,10 @@ void HistoryWidget::checkPinnedBarState() { return; } - auto barContent = HistoryView::PinnedBarContent( - &session(), - _pinnedTracker->shownMessageId()); - _pinnedBar = std::make_unique(this); + _pinnedBar = std::make_unique(this, [=] { + return controller()->isGifPausedAtLeastFor( + Window::GifPauseReason::Any); + }); rpl::combine( Info::Profile::SharedMediaCountValue( _peer, @@ -6389,7 +6390,11 @@ void HistoryWidget::checkPinnedBarState() { ) | rpl::start_with_next([=](bool many, HistoryItem *item) { refreshPinnedBarButton(many, item); }, _pinnedBar->lifetime()); - _pinnedBar->setContent(std::move(barContent)); + + _pinnedBar->setContent(HistoryView::PinnedBarContent( + &session(), + _pinnedTracker->shownMessageId(), + [bar = _pinnedBar.get()] { bar->update(); })); controller()->adaptive().oneColumnValue( ) | rpl::start_with_next([=](bool one) { @@ -7417,10 +7422,15 @@ void HistoryWidget::messageDataReceived( } void HistoryWidget::updateReplyEditText(not_null item) { + const auto context = Core::MarkedTextContext{ + .session = &session(), + .customEmojiRepaint = [=] { updateField(); }, + }; _replyEditMsgText.setMarkedText( st::messageTextStyle, item->inReplyText(), - Ui::DialogTextOptions()); + Ui::DialogTextOptions(), + context); if (!_field->isHidden() || isRecording()) { _fieldBarCancel->show(); updateMouseTracking(); @@ -7518,10 +7528,15 @@ void HistoryWidget::updateForwardingTexts() { } } _toForwardFrom.setText(st::msgNameStyle, from, Ui::NameTextOptions()); + const auto context = Core::MarkedTextContext{ + .session = &session(), + .customEmojiRepaint = [=] { updateField(); }, + }; _toForwardText.setMarkedText( st::messageTextStyle, text, - Ui::DialogTextOptions()); + Ui::DialogTextOptions(), + context); _toForwardNameVersion = keepNames ? version : keepCaptions ? -1 : -2; } @@ -7570,7 +7585,7 @@ void HistoryWidget::updateReplyToName() { } void HistoryWidget::updateField() { - auto fieldAreaTop = _scroll->y() + _scroll->height(); + const auto fieldAreaTop = _scroll->y() + _scroll->height(); rtlupdate(0, fieldAreaTop, width(), height() - fieldAreaTop); } @@ -7594,6 +7609,8 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) { backh += st::historyReplyHeight; } auto drawWebPagePreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed; + p.setInactive( + controller()->isGifPausedAtLeastFor(Window::GifPauseReason::Any)); p.fillRect(myrtlrect(0, backy, width(), backh), st::historyReplyBg); if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) { auto replyLeft = st::historyReplySkip; diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 501d895e4..c932f83bd 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -944,6 +944,9 @@ void Element::unloadHeavyPart() { if (_heavyCustomEmoji) { _heavyCustomEmoji = false; data()->_text.unloadCustomEmoji(); + if (const auto reply = data()->Get()) { + reply->replyToText.unloadCustomEmoji(); + } } } diff --git a/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp b/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp index b76757584..7e14026d8 100644 --- a/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp +++ b/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_pinned_tracker.h" #include "history/history_item.h" #include "history/history.h" +#include "core/ui_integration.h" #include "base/weak_ptr.h" #include "apiwrap.h" #include "styles/style_chat.h" @@ -23,16 +24,22 @@ namespace HistoryView { namespace { [[nodiscard]] Ui::MessageBarContent ContentWithoutPreview( - not_null item) { + not_null item, + Fn repaint) { return Ui::MessageBarContent{ .text = item->inReplyText(), + .context = Core::MarkedTextContext{ + .session = &item->history()->session(), + .customEmojiRepaint = std::move(repaint), + }, }; } [[nodiscard]] Ui::MessageBarContent ContentWithPreview( not_null item, - Image *preview) { - auto result = ContentWithoutPreview(item); + Image *preview, + Fn repaint) { + auto result = ContentWithoutPreview(item, std::move(repaint)); if (!preview) { static const auto kEmpty = [&] { const auto size = st::historyReplyHeight * cIntRetinaFactor(); @@ -51,14 +58,15 @@ namespace { } [[nodiscard]] rpl::producer ContentByItem( - not_null item) { + not_null item, + Fn repaint) { return item->history()->session().changes().messageFlagsValue( item, Data::MessageUpdate::Flag::Edited ) | rpl::map([=]() -> rpl::producer { const auto media = item->media(); if (!media || !media->hasReplyPreview()) { - return rpl::single(ContentWithoutPreview(item)); + return rpl::single(ContentWithoutPreview(item, repaint)); } constexpr auto kFullLoaded = 2; constexpr auto kSomeLoaded = 1; @@ -82,7 +90,7 @@ namespace { }) | rpl::then( rpl::single(kFullLoaded) ) | rpl::map([=] { - return ContentWithPreview(item, media->replyPreview()); + return ContentWithPreview(item, media->replyPreview(), repaint); }); }) | rpl::flatten_latest(); } @@ -90,11 +98,12 @@ namespace { [[nodiscard]] rpl::producer ContentByItemId( not_null session, FullMsgId id, + Fn repaint, bool alreadyLoaded = false) { if (!id) { return rpl::single(Ui::MessageBarContent()); } else if (const auto item = session->data().message(id)) { - return ContentByItem(item); + return ContentByItem(item, repaint); } else if (alreadyLoaded) { return rpl::single(Ui::MessageBarContent()); // Deleted message?.. } @@ -110,7 +119,7 @@ namespace { return std::move( load ) | rpl::then(rpl::deferred([=] { - return ContentByItemId(session, id, true); + return ContentByItemId(session, id, repaint, true); })); } @@ -137,20 +146,23 @@ auto WithPinnedTitle(not_null session, PinnedId id) { rpl::producer MessageBarContentByItemId( not_null session, - FullMsgId id) { - return ContentByItemId(session, id); + FullMsgId id, + Fn repaint) { + return ContentByItemId(session, id, std::move(repaint)); } rpl::producer PinnedBarContent( not_null session, - rpl::producer id) { + rpl::producer id, + Fn repaint) { return std::move( id ) | rpl::distinct_until_changed( ) | rpl::map([=](PinnedId id) { return ContentByItemId( session, - id.message + id.message, + repaint ) | rpl::map(WithPinnedTitle(session, id)); }) | rpl::flatten_latest(); } diff --git a/Telegram/SourceFiles/history/view/history_view_pinned_bar.h b/Telegram/SourceFiles/history/view/history_view_pinned_bar.h index 605091399..535cabc6c 100644 --- a/Telegram/SourceFiles/history/view/history_view_pinned_bar.h +++ b/Telegram/SourceFiles/history/view/history_view_pinned_bar.h @@ -25,7 +25,8 @@ namespace HistoryView { [[nodiscard]] rpl::producer MessageBarContentByItemId( not_null session, - FullMsgId id); + FullMsgId id, + Fn repaint); enum class PinnedIdType; struct PinnedId { @@ -47,7 +48,8 @@ struct PinnedId { }; [[nodiscard]] rpl::producer PinnedBarContent( not_null session, - rpl::producer id); + rpl::producer id, + Fn repaint); [[nodiscard]] rpl::producer PinnedBarItemWithReplyMarkup( not_null session, diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index a37c55601..f39f7563a 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -90,10 +90,12 @@ bool CanSendFiles(not_null data) { rpl::producer RootViewContent( not_null history, - MsgId rootId) { + MsgId rootId, + Fn repaint) { return MessageBarContentByItemId( &history->session(), - FullMsgId(history->peer->id, rootId) + FullMsgId(history->peer->id, rootId), + std::move(repaint) ) | rpl::map([=](Ui::MessageBarContent &&content) { const auto item = history->owner().message(history->peer, rootId); if (!item) { @@ -387,14 +389,19 @@ void RepliesWidget::setupRoot() { } void RepliesWidget::setupRootView() { - auto content = rpl::combine( - RootViewContent(_history, _rootId), + _rootView = std::make_unique(this, [=] { + return controller()->isGifPausedAtLeastFor( + Window::GifPauseReason::Any); + }); + _rootView->setContent(rpl::combine( + RootViewContent( + _history, + _rootId, + [bar = _rootView.get()] { bar->update(); }), _rootVisible.value() ) | rpl::map([=](Ui::MessageBarContent &&content, bool shown) { return shown ? std::move(content) : Ui::MessageBarContent(); - }); - _rootView = std::make_unique(this); - _rootView->setContent(std::move(content)); + })); controller()->adaptive().oneColumnValue( ) | rpl::start_with_next([=](bool one) { diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index 7d7c73b79..f98b67194 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -250,6 +250,7 @@ void BotAction::validateIcon() { _mask = QImage( size * style::DevicePixelRatio(), QImage::Format_ARGB32_Premultiplied); + _mask.setDevicePixelRatio(style::DevicePixelRatio()); _mask.fill(Qt::transparent); { auto p = QPainter(&_mask); diff --git a/Telegram/SourceFiles/ui/chat/message_bar.cpp b/Telegram/SourceFiles/ui/chat/message_bar.cpp index 9710811ca..cfce4ec85 100644 --- a/Telegram/SourceFiles/ui/chat/message_bar.cpp +++ b/Telegram/SourceFiles/ui/chat/message_bar.cpp @@ -41,9 +41,13 @@ namespace { } // namespace -MessageBar::MessageBar(not_null parent, const style::MessageBar &st) +MessageBar::MessageBar( + not_null parent, + const style::MessageBar &st, + Fn customEmojiPaused) : _st(st) -, _widget(parent) { +, _widget(parent) +, _customEmojiPaused(std::move(customEmojiPaused)) { setup(); style::PaletteChanged( @@ -57,6 +61,7 @@ void MessageBar::setup() { _widget.paintRequest( ) | rpl::start_with_next([=](QRect rect) { auto p = Painter(&_widget); + p.setInactive(_customEmojiPaused()); paint(p); }, _widget.lifetime()); } @@ -187,7 +192,11 @@ void MessageBar::tweenTo(MessageBarContent &&content) { void MessageBar::updateFromContent(MessageBarContent &&content) { _content = std::move(content); _title.setText(_st.title, _content.title); - _text.setMarkedText(_st.text, _content.text, Ui::DialogTextOptions()); + _text.setMarkedText( + _st.text, + _content.text, + Ui::DialogTextOptions(), + _content.context); _image = prepareImage(_content.preview); } diff --git a/Telegram/SourceFiles/ui/chat/message_bar.h b/Telegram/SourceFiles/ui/chat/message_bar.h index 1009f1830..52ce084f7 100644 --- a/Telegram/SourceFiles/ui/chat/message_bar.h +++ b/Telegram/SourceFiles/ui/chat/message_bar.h @@ -23,13 +23,17 @@ struct MessageBarContent { int count = 1; QString title; TextWithEntities text; + std::any context; QImage preview; style::margins margins; }; class MessageBar final { public: - MessageBar(not_null parent, const style::MessageBar &st); + MessageBar( + not_null parent, + const style::MessageBar &st, + Fn customEmojiPaused); void set(MessageBarContent &&content); void set(rpl::producer content); @@ -100,6 +104,7 @@ private: const style::MessageBar &_st; Ui::RpWidget _widget; + Fn _customEmojiPaused; MessageBarContent _content; rpl::lifetime _contentLifetime; Ui::Text::String _title, _text; diff --git a/Telegram/SourceFiles/ui/chat/pinned_bar.cpp b/Telegram/SourceFiles/ui/chat/pinned_bar.cpp index a8190490a..e9747fbe5 100644 --- a/Telegram/SourceFiles/ui/chat/pinned_bar.cpp +++ b/Telegram/SourceFiles/ui/chat/pinned_bar.cpp @@ -18,9 +18,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { -PinnedBar::PinnedBar(not_null parent) +PinnedBar::PinnedBar(not_null parent, Fn customEmojiPaused) : _wrap(parent, object_ptr(parent)) -, _shadow(std::make_unique(_wrap.parentWidget())) { +, _shadow(std::make_unique(_wrap.parentWidget())) +, _customEmojiPaused(std::move(customEmojiPaused)) { _wrap.hide(anim::type::instant); _shadow->hide(); @@ -133,7 +134,8 @@ void PinnedBar::createControls() { _bar = std::make_unique( _wrap.entity(), - st::defaultMessageBar); + st::defaultMessageBar, + _customEmojiPaused); if (_right.button) { _right.button->raise(); } @@ -205,6 +207,12 @@ void PinnedBar::raise() { _shadow->raise(); } +void PinnedBar::update() { + if (_bar) { + _bar->widget()->update(); + } +} + void PinnedBar::finishAnimating() { _wrap.finishAnimating(); } diff --git a/Telegram/SourceFiles/ui/chat/pinned_bar.h b/Telegram/SourceFiles/ui/chat/pinned_bar.h index 9e4ff87dc..b5fb8f9b8 100644 --- a/Telegram/SourceFiles/ui/chat/pinned_bar.h +++ b/Telegram/SourceFiles/ui/chat/pinned_bar.h @@ -22,12 +22,13 @@ class RpWidget; class PinnedBar final { public: - PinnedBar(not_null parent); + PinnedBar(not_null parent, Fn customEmojiPaused); ~PinnedBar(); void show(); void hide(); void raise(); + void update(); void finishAnimating(); void setShadowGeometryPostprocess(Fn postprocess); @@ -60,6 +61,7 @@ private: } _right; std::unique_ptr _shadow; + Fn _customEmojiPaused; rpl::event_stream<> _barClicks; Fn _shadowGeometryPostprocess; bool _shouldBeShown = false;