From d4810713cb521f6dfbcad7ec1cfd2f871179899c Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 6 Sep 2022 17:08:20 +0400 Subject: [PATCH] Fly-animate reactions from the new context menu. --- .../SourceFiles/boxes/edit_caption_box.cpp | 4 +- Telegram/SourceFiles/boxes/send_files_box.cpp | 4 +- .../chat_helpers/emoji_list_widget.cpp | 103 ++++++++++++------ .../chat_helpers/emoji_list_widget.h | 31 ++++-- .../chat_helpers/tabbed_selector.cpp | 4 +- .../chat_helpers/tabbed_selector.h | 8 +- .../history/history_inner_widget.cpp | 5 +- .../SourceFiles/history/history_widget.cpp | 8 +- .../history_view_compose_controls.cpp | 9 +- .../history/view/history_view_list_widget.cpp | 5 +- .../history_view_reactions_button.cpp | 2 +- .../history_view_reactions_selector.cpp | 46 ++++++-- .../history_view_reactions_selector.h | 1 + .../reactions/history_view_reactions_strip.h | 3 +- .../info/profile/info_profile_cover.cpp | 14 ++- .../message_sending_animation_common.h | 2 + 16 files changed, 169 insertions(+), 80 deletions(-) diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index 46d3e8541..1ab8dbf0e 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -502,8 +502,8 @@ void EditCaptionBox::setupEmojiPanel() { _emojiPanel->hide(); _emojiPanel->selector()->setCurrentPeer(_historyItem->history()->peer); _emojiPanel->selector()->emojiChosen( - ) | rpl::start_with_next([=](EmojiPtr emoji) { - Ui::InsertEmojiAtCursor(_field->textCursor(), emoji); + ) | rpl::start_with_next([=](Selector::EmojiChosen data) { + Ui::InsertEmojiAtCursor(_field->textCursor(), data.emoji); }, lifetime()); _emojiPanel->selector()->customEmojiChosen( ) | rpl::start_with_next([=](Selector::FileChosen data) { diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 1ad674737..1cf3d45c6 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -744,8 +744,8 @@ void SendFilesBox::setupEmojiPanel() { _emojiPanel->selector()->setAllowEmojiWithoutPremium( _allowEmojiWithoutPremium); _emojiPanel->selector()->emojiChosen( - ) | rpl::start_with_next([=](EmojiPtr emoji) { - Ui::InsertEmojiAtCursor(_caption->textCursor(), emoji); + ) | rpl::start_with_next([=](Selector::EmojiChosen data) { + Ui::InsertEmojiAtCursor(_caption->textCursor(), data.emoji); }, lifetime()); _emojiPanel->selector()->customEmojiChosen( ) | rpl::start_with_next([=](Selector::FileChosen data) { diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp index ddef52c6b..94e686e2c 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp @@ -46,6 +46,8 @@ constexpr auto kAppearDuration = 0.3; using Core::RecentEmojiId; using Core::RecentEmojiDocument; +using EmojiChosen = TabbedSelector::EmojiChosen; +using FileChosen = TabbedSelector::FileChosen; } // namespace @@ -64,8 +66,8 @@ public: void hideAnimated(); void hideFast(); - rpl::producer chosen() const; - rpl::producer<> hidden() const; + [[nodiscard]] rpl::producer chosen() const; + [[nodiscard]] rpl::producer<> hidden() const; protected: void paintEvent(QPaintEvent *e) override; @@ -98,7 +100,7 @@ private: QPixmap _cache; Ui::Animations::Simple _a_opacity; - rpl::event_stream _chosen; + rpl::event_stream _chosen; rpl::event_stream<> _hidden; }; @@ -204,7 +206,7 @@ void EmojiColorPicker::handleMouseRelease(QPoint globalPos) { updateSelected(); if (_selected >= 0 && (pressed < 0 || _selected == pressed)) { - _chosen.fire_copy(_variants[_selected]); + _chosen.fire_copy({ .emoji = _variants[_selected] }); } _ignoreShow = true; hideAnimated(); @@ -254,7 +256,7 @@ void EmojiColorPicker::hideFast() { _hidden.fire({}); } -rpl::producer EmojiColorPicker::chosen() const { +rpl::producer EmojiColorPicker::chosen() const { return _chosen.events(); } @@ -413,8 +415,8 @@ EmojiListWidget::EmojiListWidget( } _picker->chosen( - ) | rpl::start_with_next([=](EmojiPtr emoji) { - colorChosen(emoji); + ) | rpl::start_with_next([=](EmojiChosen data) { + colorChosen(data); }, lifetime()); _picker->hidden( @@ -494,17 +496,15 @@ void EmojiListWidget::repaintCustom(uint64 setId) { }); } -rpl::producer EmojiListWidget::chosen() const { +rpl::producer EmojiListWidget::chosen() const { return _chosen.events(); } -auto EmojiListWidget::customChosen() const --> rpl::producer { +rpl::producer EmojiListWidget::customChosen() const { return _customChosen.events(); } -auto EmojiListWidget::premiumChosen() const --> rpl::producer> { +rpl::producer EmojiListWidget::premiumChosen() const { return _premiumChosen.events(); } @@ -811,33 +811,37 @@ base::unique_qptr EmojiListWidget::fillContextMenu( auto menu = base::make_unique_q( this, st::defaultPopupMenu); + const auto selectWith = [=](TimeId scheduled) { + selectCustom( + lookupChosen(chosen, nullptr, { .scheduled = scheduled })); + }; for (const auto &value : { 3600, 3600 * 8, 3600 * 24, 3600 * 24 * 7 }) { const auto text = tr::lng_emoji_status_menu_duration_any( tr::now, lt_duration, Ui::FormatMuteFor(value)); menu->addAction(text, crl::guard(this, [=] { - selectCustom( - chosen, - { .scheduled = base::unixtime::now() + value } ); + selectWith(base::unixtime::now() + value); })); } - const auto options = Api::SendOptions{ - .scheduled = TabbedSelector::kPickCustomTimeId, - }; menu->addAction( tr::lng_manage_messages_ttl_after_custom(tr::now), - crl::guard(this, [=] { selectCustom(chosen, options); })); + crl::guard(this, [=] { selectWith( + TabbedSelector::kPickCustomTimeId); })); return menu; } void EmojiListWidget::paintEvent(QPaintEvent *e) { Painter p(this); - _repaintsScheduled.clear(); - const auto clip = e ? e->rect() : rect(); - if (st().bg->c.alpha() > 0) { + + _repaintsScheduled.clear(); + if (_grabbingChosen) { + p.setCompositionMode(QPainter::CompositionMode_Source); + p.fillRect(clip, Qt::transparent); + p.setCompositionMode(QPainter::CompositionMode_SourceOver); + } else if (st().bg->c.alpha() > 0) { p.fillRect(clip, st().bg); } @@ -1121,6 +1125,37 @@ EmojiPtr EmojiListWidget::lookupOverEmoji(const OverEmoji *over) const { : nullptr; } +EmojiChosen EmojiListWidget::lookupChosen( + EmojiPtr emoji, + not_null over) { + return { + .emoji = emoji, + .messageSendingFrom = { + .type = Ui::MessageSendingAnimationFrom::Type::Emoji, + .globalStartGeometry = mapToGlobal( + emojiRect(over->section, over->index)), + }, + }; +} + +FileChosen EmojiListWidget::lookupChosen( + not_null custom, + const OverEmoji *over, + Api::SendOptions options) { + _grabbingChosen = true; + const auto guard = gsl::finally([&] { _grabbingChosen = false; }); + const auto rect = emojiRect(over->section, over->index); + return { + .document = custom, + .options = options, + .messageSendingFrom = { + .type = Ui::MessageSendingAnimationFrom::Type::Emoji, + .globalStartGeometry = over ? mapToGlobal(rect) : QRect(), + .frame = over ? Ui::GrabWidgetToImage(this, rect) : QImage(), + }, + }; +} + void EmojiListWidget::mousePressEvent(QMouseEvent *e) { _lastMousePos = e->globalPos(); updateSelected(); @@ -1187,9 +1222,9 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) { if (emoji->hasVariants() && !_picker->isHidden()) { return; } - selectEmoji(emoji); + selectEmoji(lookupChosen(emoji, over)); } else if (const auto custom = lookupCustomEmoji(index, section)) { - selectCustom(custom); + selectCustom(lookupChosen(custom, over)); } } else if (const auto set = std::get_if(&pressed)) { Assert(set->section >= _staticCount @@ -1241,18 +1276,17 @@ void EmojiListWidget::removeSet(uint64 setId) { } } -void EmojiListWidget::selectEmoji(EmojiPtr emoji) { - Core::App().settings().incrementRecentEmoji({ emoji }); - _chosen.fire_copy(emoji); +void EmojiListWidget::selectEmoji(EmojiChosen data) { + Core::App().settings().incrementRecentEmoji({ data.emoji }); + _chosen.fire(std::move(data)); } -void EmojiListWidget::selectCustom( - not_null document, - Api::SendOptions options) { +void EmojiListWidget::selectCustom(FileChosen data) { + const auto document = data.document; if (document->isPremiumEmoji() && !document->session().premium() && !_allowWithoutPremium) { - _premiumChosen.fire_copy(document); + _premiumChosen.fire(std::move(data)); return; } auto &settings = Core::App().settings(); @@ -1262,7 +1296,7 @@ void EmojiListWidget::selectCustom( document->session().isTestMode(), } }); } - _customChosen.fire({ .document = document, .options = options }); + _customChosen.fire(std::move(data)); } void EmojiListWidget::showPicker() { @@ -1408,7 +1442,8 @@ QRect EmojiListWidget::emojiRect(int section, int index) const { return QRect(x, y, _singleSize.width(), _singleSize.height()); } -void EmojiListWidget::colorChosen(EmojiPtr emoji) { +void EmojiListWidget::colorChosen(EmojiChosen data) { + const auto emoji = data.emoji; if (emoji->hasVariants()) { Core::App().settings().saveEmojiVariant(emoji); } @@ -1420,7 +1455,7 @@ void EmojiListWidget::colorChosen(EmojiPtr emoji) { _emoji[over->section][over->index] = emoji; rtlupdate(emojiRect(over->section, over->index)); } - selectEmoji(emoji); + selectEmoji(data); _picker->hideAnimated(); } diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h index af17b130c..f0d9389bb 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h @@ -85,6 +85,9 @@ class EmojiListWidget , public Ui::AbstractTooltipShower { public: using Mode = EmojiListMode; + using EmojiChosen = TabbedSelector::EmojiChosen; + using FileChosen = TabbedSelector::FileChosen; + EmojiListWidget( QWidget *parent, not_null controller, @@ -110,11 +113,9 @@ public: void refreshEmoji(); - [[nodiscard]] rpl::producer chosen() const; - [[nodiscard]] auto customChosen() const - -> rpl::producer; - [[nodiscard]] auto premiumChosen() const - -> rpl::producer>; + [[nodiscard]] rpl::producer chosen() const; + [[nodiscard]] rpl::producer customChosen() const; + [[nodiscard]] rpl::producer premiumChosen() const; [[nodiscard]] rpl::producer<> jumpedToPremium() const; void provideRecent(const std::vector &customRecentList); @@ -237,7 +238,7 @@ private: void showPicker(); void pickerHidden(); - void colorChosen(EmojiPtr emoji); + void colorChosen(EmojiChosen data); bool checkPickerHide(); void refreshCustom(); void unloadNotSeenCustom(int visibleTop, int visibleBottom); @@ -253,10 +254,15 @@ private: [[nodiscard]] DocumentData *lookupCustomEmoji( int index, int section) const; - void selectEmoji(EmojiPtr emoji); - void selectCustom( - not_null document, + [[nodiscard]] EmojiChosen lookupChosen( + EmojiPtr emoji, + not_null over); + [[nodiscard]] FileChosen lookupChosen( + not_null custom, + const OverEmoji *over, Api::SendOptions options = Api::SendOptions()); + void selectEmoji(EmojiChosen data); + void selectCustom(FileChosen data); void paint(QPainter &p, ExpandingContext context, QRect clip); void drawCollapsedBadge(QPainter &p, QPoint position, int count); void drawRecent( @@ -343,6 +349,7 @@ private: base::flat_set _repaintsScheduled; std::unique_ptr _emojiStatusColor; bool _recentPainted = false; + bool _grabbingChosen = false; QVector _emoji[kEmojiSectionCount]; std::vector _custom; base::flat_map _customEmoji; @@ -373,9 +380,9 @@ private: object_ptr _picker; base::Timer _showPickerTimer; - rpl::event_stream _chosen; - rpl::event_stream _customChosen; - rpl::event_stream> _premiumChosen; + rpl::event_stream _chosen; + rpl::event_stream _customChosen; + rpl::event_stream _premiumChosen; rpl::event_stream<> _jumpedToPremium; }; diff --git a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp index 8db92311d..765b9abb2 100644 --- a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp +++ b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp @@ -492,7 +492,7 @@ bool TabbedSelector::hasMasksTab() const { return _hasMasksTab; } -rpl::producer TabbedSelector::emojiChosen() const { +auto TabbedSelector::emojiChosen() const -> rpl::producer { return emoji()->chosen(); } @@ -501,7 +501,7 @@ auto TabbedSelector::customEmojiChosen() const -> rpl::producer { } auto TabbedSelector::premiumEmojiChosen() const --> rpl::producer> { +-> rpl::producer { return emoji()->premiumChosen(); } diff --git a/Telegram/SourceFiles/chat_helpers/tabbed_selector.h b/Telegram/SourceFiles/chat_helpers/tabbed_selector.h index 911991833..a01c546ca 100644 --- a/Telegram/SourceFiles/chat_helpers/tabbed_selector.h +++ b/Telegram/SourceFiles/chat_helpers/tabbed_selector.h @@ -70,6 +70,10 @@ public: not_null photo; Api::SendOptions options; }; + struct EmojiChosen { + EmojiPtr emoji; + Ui::MessageSendingAnimationFrom messageSendingFrom; + }; using InlineChosen = InlineBots::ResultSelected; enum class Mode { Full, @@ -92,9 +96,9 @@ public: Main::Session &session() const; Window::GifPauseReason level() const; - rpl::producer emojiChosen() const; + rpl::producer emojiChosen() const; rpl::producer customEmojiChosen() const; - rpl::producer> premiumEmojiChosen() const; + rpl::producer premiumEmojiChosen() const; rpl::producer fileChosen() const; rpl::producer photoChosen() const; rpl::producer inlineResultChosen() const; diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 84d4984ff..59d0cd095 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -480,10 +480,13 @@ void HistoryInner::reactionChosen(const ChosenReaction &reaction) { return; } else if (const auto view = item->mainView()) { if (const auto top = itemTop(view); top >= 0) { + const auto geometry = reaction.localGeometry.isEmpty() + ? mapFromGlobal(reaction.globalGeometry) + : reaction.localGeometry; view->animateReaction({ .id = reaction.id, .flyIcon = reaction.icon, - .flyFrom = reaction.geometry.translated(0, -top), + .flyFrom = geometry.translated(0, -top), }); } } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 851eb8903..5d72f31e6 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -1067,8 +1067,8 @@ void HistoryWidget::initTabbedSelector() { selector->emojiChosen( ) | rpl::filter([=] { return !isHidden() && !_field->isHidden(); - }) | rpl::start_with_next([=](EmojiPtr emoji) { - Ui::InsertEmojiAtCursor(_field->textCursor(), emoji); + }) | rpl::start_with_next([=](Selector::EmojiChosen data) { + Ui::InsertEmojiAtCursor(_field->textCursor(), data.emoji); }, lifetime()); selector->customEmojiChosen( @@ -1081,8 +1081,8 @@ void HistoryWidget::initTabbedSelector() { selector->premiumEmojiChosen( ) | rpl::filter([=] { return !isHidden() && !_field->isHidden(); - }) | rpl::start_with_next([=](not_null document) { - showPremiumToast(document); + }) | rpl::start_with_next([=](Selector::FileChosen data) { + showPremiumToast(data.document); }, lifetime()); selector->fileChosen( 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 23862214b..ef7632918 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -1857,9 +1857,10 @@ void ComposeControls::initTabbedSelector() { return base::EventFilterResult::Continue; }); + using EmojiChosen = ChatHelpers::TabbedSelector::EmojiChosen; selector->emojiChosen( - ) | rpl::start_with_next([=](EmojiPtr emoji) { - Ui::InsertEmojiAtCursor(_field->textCursor(), emoji); + ) | rpl::start_with_next([=](EmojiChosen data) { + Ui::InsertEmojiAtCursor(_field->textCursor(), data.emoji); }, wrap->lifetime()); using FileChosen = ChatHelpers::TabbedSelector::FileChosen; @@ -1869,9 +1870,9 @@ void ComposeControls::initTabbedSelector() { }, wrap->lifetime()); selector->premiumEmojiChosen( - ) | rpl::start_with_next([=](not_null document) { + ) | rpl::start_with_next([=](FileChosen data) { if (_unavailableEmojiPasted) { - _unavailableEmojiPasted(document); + _unavailableEmojiPasted(data.document); } }, wrap->lifetime()); diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 6eedfc271..7f68a446f 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -374,11 +374,14 @@ ListWidget::ListWidget( if (!ranges::contains(item->chosenReactions(), reaction.id)) { return; } else if (const auto view = viewForItem(item)) { + const auto geometry = reaction.localGeometry.isEmpty() + ? mapFromGlobal(reaction.globalGeometry) + : reaction.localGeometry; if (const auto top = itemTop(view); top >= 0) { view->animateReaction({ .id = reaction.id, .flyIcon = reaction.icon, - .flyFrom = reaction.geometry.translated(0, -top), + .flyFrom = geometry.translated(0, -top), }); } } diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp index cc2fe9f9f..a3c2304fe 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_button.cpp @@ -374,7 +374,7 @@ ChosenReaction Manager::lookupChosen(const ReactionId &id) const { : local; const auto rect = QRect(geometry.topLeft() + QPoint(0, top), _outer); const auto imageSize = _strip.computeOverSize(); - result.geometry = QRect( + result.localGeometry = QRect( rect.x() + (rect.width() - imageSize) / 2, rect.y() + (rect.height() - imageSize) / 2, imageSize, diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.cpp b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.cpp index bc8a26cd3..7ffca12c7 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.cpp +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.cpp @@ -624,11 +624,33 @@ void Selector::mouseReleaseEvent(QMouseEvent *e) { expand(); } else if (const auto id = std::get_if(&selected)) { if (!id->empty()) { - _chosen.fire({ .id = *id }); + _chosen.fire(lookupChosen(*id)); } } } +ChosenReaction Selector::lookupChosen(const Data::ReactionId &id) const { + Expects(_strip != nullptr); + + auto result = ChosenReaction{ + .id = id, + }; + const auto index = _strip->fillChosenIconGetIndex(result); + if (result.icon.isNull()) { + return result; + } + const auto between = st::reactionCornerSkip; + const auto oneHeight = (st::reactionCornerSize.height() + between); + const auto rect = QRect(_skipx + index * _size, _skipy, _size, _size); + const auto imageSize = _strip->computeOverSize(); + result.globalGeometry = mapToGlobal(QRect( + _inner.x() + rect.x() + (rect.width() - imageSize) / 2, + _inner.y() + rect.y() + (rect.height() - imageSize) / 2, + imageSize, + imageSize)); + return result; +} + void Selector::expand() { if (_expandScheduled) { return; @@ -759,19 +781,19 @@ void Selector::createList(not_null controller) { ).data(); rpl::merge( - _list->customChosen( - ) | rpl::map([=](const TabbedSelector::FileChosen &chosen) { - return chosen.document; - }), + _list->customChosen(), _list->premiumChosen() - ) | rpl::start_with_next([=](not_null document) { - const auto id = DocumentId{ document->id }; + ) | rpl::start_with_next([=](TabbedSelector::FileChosen data) { + const auto id = DocumentId{ data.document->id }; const auto i = defaultReactionIds.find(id); - if (i != end(defaultReactionIds)) { - _chosen.fire({ .id = { i->second } }); - } else { - _chosen.fire({ .id = { id } }); - } + const auto reactionId = (i != end(defaultReactionIds)) + ? Data::ReactionId{ i->second } + : Data::ReactionId{ id }; + _chosen.fire({ + .id = reactionId, + .icon = data.messageSendingFrom.frame, + .globalGeometry = data.messageSendingFrom.globalStartGeometry, + }); }, _list->lifetime()); _list->jumpedToPremium( diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.h b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.h index 313ef86fb..f13907880 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.h +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.h @@ -117,6 +117,7 @@ private: void cacheExpandIcon(); void createList(not_null controller); void finishExpand(); + ChosenReaction lookupChosen(const Data::ReactionId &id) const; const base::weak_ptr _parentController; const Data::PossibleItemReactions _reactions; diff --git a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h index 0de93fd6f..56726ae88 100644 --- a/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h +++ b/Telegram/SourceFiles/history/view/reactions/history_view_reactions_strip.h @@ -28,7 +28,8 @@ struct ChosenReaction { FullMsgId context; Data::ReactionId id; QImage icon; - QRect geometry; + QRect localGeometry; + QRect globalGeometry; explicit operator bool() const { return context && !id.empty(); diff --git a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp index 8fe55b2a2..3d3a74aba 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp @@ -327,6 +327,7 @@ void EmojiStatusPanel::create( struct Chosen { DocumentId id = 0; TimeId until = 0; + Ui::MessageSendingAnimationFrom animation; }; _panel->selector()->contextMenuRequested( @@ -336,12 +337,21 @@ void EmojiStatusPanel::create( auto statusChosen = _panel->selector()->customEmojiChosen( ) | rpl::map([=](Selector::FileChosen data) { - return Chosen{ data.document->id, data.options.scheduled }; + return Chosen{ + .id = data.document->id, + .until = data.options.scheduled, + .animation = data.messageSendingFrom, + }; + }); + + auto emojiChosen = _panel->selector()->emojiChosen( + ) | rpl::map([=](Selector::EmojiChosen data) { + return Chosen{ .animation = data.messageSendingFrom }; }); rpl::merge( std::move(statusChosen), - _panel->selector()->emojiChosen() | rpl::map_to(Chosen()) + std::move(emojiChosen) ) | rpl::start_with_next([=](const Chosen chosen) { if (chosen.until == ChatHelpers::TabbedSelector::kPickCustomTimeId) { controller->show(Box(PickUntilBox, [=](TimeId seconds) { diff --git a/Telegram/SourceFiles/ui/effects/message_sending_animation_common.h b/Telegram/SourceFiles/ui/effects/message_sending_animation_common.h index c2faaeb4c..a3877b615 100644 --- a/Telegram/SourceFiles/ui/effects/message_sending_animation_common.h +++ b/Telegram/SourceFiles/ui/effects/message_sending_animation_common.h @@ -14,10 +14,12 @@ struct MessageSendingAnimationFrom { None, Sticker, Gif, + Emoji, }; Type type = Type::None; std::optional localId; QRect globalStartGeometry; + QImage frame; bool crop = false; };