From 8c8cbbbc834f5e2277f84c6f1f9e85177513b85d Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 1 Jul 2022 20:06:23 +0400 Subject: [PATCH] Display custom emoji in custom notifications. --- .../data/stickers/data_custom_emoji.cpp | 3 +- .../ui/text/custom_emoji_instance.cpp | 1 + .../window/notifications_manager_default.cpp | 99 +++++++++++++------ .../window/notifications_manager_default.h | 8 +- 4 files changed, 80 insertions(+), 31 deletions(-) diff --git a/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp b/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp index 47fb2bdc1..a288db74a 100644 --- a/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp +++ b/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp @@ -237,7 +237,8 @@ void CustomEmojiLoader::lookupDone( auto loader = [=] { return std::make_unique(document, tag); }; - lookup->process->loaded(Ui::CustomEmoji::Cached( + auto done = std::move(lookup->process->loaded); + done(Ui::CustomEmoji::Cached( SerializeCustomEmojiId(document), std::move(loader), std::move(*result))); diff --git a/Telegram/SourceFiles/ui/text/custom_emoji_instance.cpp b/Telegram/SourceFiles/ui/text/custom_emoji_instance.cpp index 04caf9549..7f34e7b67 100644 --- a/Telegram/SourceFiles/ui/text/custom_emoji_instance.cpp +++ b/Telegram/SourceFiles/ui/text/custom_emoji_instance.cpp @@ -527,6 +527,7 @@ void Instance::paint( _state = std::move(*caching); } else if (auto cached = std::get_if(&result)) { _state = std::move(*cached); + repaint(); } else { Unexpected("Value in Loader::LoadResult."); } diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 7bc9ffc89..365506f14 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "platform/platform_notifications_manager.h" #include "platform/platform_specific.h" #include "core/application.h" +#include "core/ui_integration.h" #include "lang/lang_keys.h" #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" @@ -732,7 +733,7 @@ void Notification::updateGeometry(int x, int y, int width, int height) { void Notification::paintEvent(QPaintEvent *e) { Painter p(this); p.setClipRect(e->rect()); - p.drawPixmap(0, 0, _cache); + p.drawImage(0, 0, _cache); auto buttonsTop = st::notifyTextTop + st::msgNameFont->height; if (a_actionsOpacity.animating()) { @@ -750,8 +751,40 @@ void Notification::actionsOpacityCallback() { } } +void Notification::customEmojiCallback() { + if (_textRepaintScheduled) { + return; + } + _textRepaintScheduled = true; + InvokeQueued(this, [=] { + _textRepaintScheduled = false; + if (_cache.isNull()) { + return; + } + Painter p(&_cache); + p.fillRect(_textRect, st::notificationBg); + paintText(p); + update(); + }); +} + +void Notification::paintText(Painter &p) { + p.setTextPalette(st::dialogsTextPalette); + p.setPen(st::dialogsTextFg); + p.setFont(st::dialogsTextFont); + _textCache.drawElided( + p, + _textRect.left(), + _textRect.top(), + _textRect.width(), + _textRect.height() / st::dialogsTextFont->height); + p.restoreTextPalette(); +} + void Notification::updateNotifyDisplay() { - if (!_history || (!_item && _forwardedCount < 2)) return; + if (!_history || (!_item && _forwardedCount < 2)) { + return; + } const auto options = manager()->getNotificationOptions( _item, @@ -810,15 +843,13 @@ void Notification::updateNotifyDisplay() { const auto composeText = !options.hideMessageText || (!_reaction.isEmpty() && !options.hideNameAndPhoto); if (composeText) { - auto itemTextCache = Ui::Text::String(itemWidth); + auto old = base::take(_textCache); + _textCache = Ui::Text::String(itemWidth); auto r = QRect( st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dialogsTextFont->height); - p.setTextPalette(st::dialogsTextPalette); - p.setPen(st::dialogsTextFg); - p.setFont(st::dialogsTextFont); const auto text = !_reaction.isEmpty() ? (!_author.isEmpty() ? Ui::Text::PlainLink(_author).append(' ') @@ -842,20 +873,27 @@ void Notification::updateNotifyDisplay() { _forwardedCount)) : QString())); const auto options = TextParseOptions{ - TextParsePlainLinks - | (_forwardedCount > 1 ? TextParseMultiline : 0), + (TextParsePlainLinks + | TextParseMarkdown + | (_forwardedCount > 1 ? TextParseMultiline : 0)), 0, 0, Qt::LayoutDirectionAuto, }; - itemTextCache.setMarkedText(st::dialogsTextStyle, text, options); - itemTextCache.drawElided( - p, - r.left(), - r.top(), - r.width(), - r.height() / st::dialogsTextFont->height); - p.restoreTextPalette(); + const auto context = Core::MarkedTextContext{ + .session = &_history->session(), + .customEmojiRepaint = [=] { customEmojiCallback(); }, + }; + _textCache.setMarkedText( + st::dialogsTextStyle, + text, + options, + context); + _textRect = r; + paintText(p); + if (!_textCache.hasCustomEmoji()) { + _textCache = Ui::Text::String(); + } } else { p.setFont(st::dialogsTextFont); p.setPen(st::dialogsTextFgService); @@ -881,7 +919,7 @@ void Notification::updateNotifyDisplay() { titleText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } - _cache = Ui::PixmapFromImage(std::move(img)); + _cache = std::move(img); if (!canReply()) { toggleActionButtons(false); } @@ -898,18 +936,21 @@ void Notification::updatePeerPhoto() { } _userpicLoaded = true; - auto img = _cache.toImage(); - { - Painter p(&img); - _peer->paintUserpicLeft( - p, - _userpicView, - st::notifyPhotoPos.x(), - st::notifyPhotoPos.y(), - width(), - st::notifyPhotoSize); - } - _cache = Ui::PixmapFromImage(std::move(img)); + Painter p(&_cache); + p.fillRect( + style::rtlrect( + QRect( + st::notifyPhotoPos, + QSize(st::notifyPhotoSize, st::notifyPhotoSize)), + width()), + st::notificationBg); + _peer->paintUserpicLeft( + p, + _userpicView, + st::notifyPhotoPos.x(), + st::notifyPhotoPos.y(), + width(), + st::notifyPhotoSize); _userpicView = nullptr; update(); } diff --git a/Telegram/SourceFiles/window/notifications_manager_default.h b/Telegram/SourceFiles/window/notifications_manager_default.h index 9816905af..28a09b770 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.h +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/notifications_manager.h" #include "ui/effects/animations.h" +#include "ui/text/text.h" #include "ui/rp_widget.h" #include "base/timer.h" #include "base/binary_guard.h" @@ -260,15 +261,20 @@ private: void changeHeight(int newHeight); void updateGeometry(int x, int y, int width, int height) override; void actionsOpacityCallback(); + void paintText(Painter &p); + void customEmojiCallback(); [[nodiscard]] Notifications::Manager::NotificationId myId() const; const not_null _peer; - QPixmap _cache; + QImage _cache; + Ui::Text::String _textCache; + QRect _textRect; bool _hideReplyButton = false; bool _actionsVisible = false; + bool _textRepaintScheduled = false; Ui::Animations::Simple a_actionsOpacity; QPixmap _buttonsCache;