From 5fb7992b04589ed8e66b8f3dfc7add1a45d0d56b Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 11 May 2024 19:08:22 +0400 Subject: [PATCH] Improve effect initial auto-play. --- Telegram/SourceFiles/data/data_types.h | 2 +- Telegram/SourceFiles/history/history.cpp | 7 +++++ Telegram/SourceFiles/history/history.h | 1 + .../history/history_inner_widget.cpp | 24 +++++++++++------ .../history/history_inner_widget.h | 1 + Telegram/SourceFiles/history/history_item.cpp | 27 +++++++++++++++---- Telegram/SourceFiles/history/history_item.h | 2 ++ .../SourceFiles/history/history_widget.cpp | 3 +++ 8 files changed, 53 insertions(+), 14 deletions(-) diff --git a/Telegram/SourceFiles/data/data_types.h b/Telegram/SourceFiles/data/data_types.h index 4d0e5b3d74..66e041c0f6 100644 --- a/Telegram/SourceFiles/data/data_types.h +++ b/Telegram/SourceFiles/data/data_types.h @@ -322,7 +322,7 @@ enum class MessageFlag : uint64 { ShortcutMessage = (1ULL << 44), - EffectWatchedLocal = (1ULL << 45), + EffectWatched = (1ULL << 45), }; inline constexpr bool is_flag_type(MessageFlag) { return true; } using MessageFlags = base::flags; diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 02a3324b9f..754791e80d 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -1753,6 +1753,10 @@ MsgId History::loadAroundId() const { return MsgId(0); } +bool History::inboxReadTillKnown() const { + return _inboxReadBefore.has_value(); +} + MsgId History::inboxReadTillId() const { return _inboxReadBefore.value_or(1) - 1; } @@ -2927,6 +2931,9 @@ void History::setInboxReadTill(MsgId upTo) { accumulate_max(*_inboxReadBefore, upTo + 1); } else { _inboxReadBefore = upTo + 1; + for (const auto &item : _items) { + item->applyEffectWatchedOnUnreadKnown(); + } } } diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 729b66045c..73695785fa 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -218,6 +218,7 @@ public: void outboxRead(MsgId upTo); void outboxRead(not_null wasRead); [[nodiscard]] MsgId loadAroundId() const; + [[nodiscard]] bool inboxReadTillKnown() const; [[nodiscard]] MsgId inboxReadTillId() const; [[nodiscard]] MsgId outboxReadTillId() const; diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 3b51df0d71..38483247d9 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -908,6 +908,14 @@ Ui::ChatPaintContext HistoryInner::preparePaintContext( }); } +void HistoryInner::startEffectOnRead(not_null item) { + if (item->history() == _history) { + if (const auto view = item->mainView()) { + _emojiInteractions->playEffectOnRead(view); + } + } +} + void HistoryInner::paintEvent(QPaintEvent *e) { if (_controller->contentOverlapped(this, e) || hasPendingResizedItems()) { @@ -962,13 +970,13 @@ void HistoryInner::paintEvent(QPaintEvent *e) { _translateTracker->add(_pinnedItem); } _translateTracker->finishBunch(); + if (!startEffects.empty()) { + for (const auto &view : startEffects) { + _emojiInteractions->playEffectOnRead(view); + } + } if (readTill && _widget->markingMessagesRead()) { session().data().histories().readInboxTill(readTill); - if (!startEffects.empty()) { - for (const auto &view : startEffects) { - _emojiInteractions->playEffectOnRead(view); - } - } } if (markingAsViewed && !readContents.empty()) { session().api().markContentsRead(readContents); @@ -1002,9 +1010,9 @@ void HistoryInner::paintEvent(QPaintEvent *e) { session().sponsoredMessages().view(item->fullId()); } else if (isUnread) { readTill = item; - if (item->hasUnwatchedEffect()) { - startEffects.emplace(view); - } + } + if (markingAsViewed && item->hasUnwatchedEffect()) { + startEffects.emplace(view); } if (markingAsViewed && item->hasViews()) { session().api().views().scheduleIncrement(item); diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index 2ab1207a16..5a11b2944a 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -174,6 +174,7 @@ public: not_null view, Element *replacing); + void startEffectOnRead(not_null item); void updateBotInfo(bool recount = true); bool wasSelectedText() const; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 7e929a816c..7cb74b1891 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -369,6 +369,9 @@ HistoryItem::HistoryItem( }) { _boostsApplied = data.vfrom_boosts_applied().value_or_empty(); + // Called only for server-received messages, not locally created ones. + applyInitialEffectWatched(); + const auto media = data.vmedia(); const auto checked = media ? CheckMessageMedia(*media) @@ -1287,17 +1290,14 @@ bool HistoryItem::hasUnreadReaction() const { } bool HistoryItem::hasUnwatchedEffect() const { - return !out() - && effectId() - && !(_flags & MessageFlag::EffectWatchedLocal) - && unread(history()); + return effectId() && !(_flags & MessageFlag::EffectWatched); } bool HistoryItem::markEffectWatched() { if (!hasUnwatchedEffect()) { return false; } - _flags |= MessageFlag::EffectWatchedLocal; + _flags |= MessageFlag::EffectWatched; return true; } @@ -3480,6 +3480,23 @@ void HistoryItem::setupForwardedComponent(const CreateConfig &config) { forwarded->imported = config.imported; } +void HistoryItem::applyInitialEffectWatched() { + if (!effectId()) { + return; + } else if (out()) { + // If this message came from the server, not generated on send. + _flags |= MessageFlag::EffectWatched; + } else if (_history->inboxReadTillId() && !unread(_history)) { + _flags |= MessageFlag::EffectWatched; + } +} + +void HistoryItem::applyEffectWatchedOnUnreadKnown() { + if (effectId() && !out() && !unread(_history)) { + _flags |= MessageFlag::EffectWatched; + } +} + bool HistoryItem::generateLocalEntitiesByReply() const { using namespace HistoryView; if (!_media) { diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 1a276a4470..1b006e35a7 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -400,6 +400,7 @@ public: void setPostAuthor(const QString &author); void setRealId(MsgId newId); void incrementReplyToTopCounter(); + void applyEffectWatchedOnUnreadKnown(); [[nodiscard]] bool emptyText() const { return _text.empty(); @@ -547,6 +548,7 @@ private: void createComponentsHelper(HistoryItemCommonFields &&fields); void createComponents(CreateConfig &&config); void setupForwardedComponent(const CreateConfig &config); + void applyInitialEffectWatched(); [[nodiscard]] bool generateLocalEntitiesByReply() const; [[nodiscard]] TextWithEntities withLocalEntities( diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index e769001801..ca3803cff8 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -3255,6 +3255,9 @@ void HistoryWidget::newItemAdded(not_null item) { if (item->showNotification()) { destroyUnreadBar(); if (markingMessagesRead()) { + if (_list && item->hasUnwatchedEffect()) { + _list->startEffectOnRead(item); + } if (item->isUnreadMention() && !item->isUnreadMedia()) { session().api().markContentsRead(item); }