Improve effect initial auto-play.

This commit is contained in:
John Preston 2024-05-11 19:08:22 +04:00
parent f371cd1af2
commit 5fb7992b04
8 changed files with 53 additions and 14 deletions

View File

@ -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<MessageFlag>;

View File

@ -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();
}
}
}

View File

@ -218,6 +218,7 @@ public:
void outboxRead(MsgId upTo);
void outboxRead(not_null<const HistoryItem*> wasRead);
[[nodiscard]] MsgId loadAroundId() const;
[[nodiscard]] bool inboxReadTillKnown() const;
[[nodiscard]] MsgId inboxReadTillId() const;
[[nodiscard]] MsgId outboxReadTillId() const;

View File

@ -908,6 +908,14 @@ Ui::ChatPaintContext HistoryInner::preparePaintContext(
});
}
void HistoryInner::startEffectOnRead(not_null<HistoryItem*> 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);

View File

@ -174,6 +174,7 @@ public:
not_null<const Element*> view,
Element *replacing);
void startEffectOnRead(not_null<HistoryItem*> item);
void updateBotInfo(bool recount = true);
bool wasSelectedText() const;

View File

@ -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) {

View File

@ -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(

View File

@ -3255,6 +3255,9 @@ void HistoryWidget::newItemAdded(not_null<HistoryItem*> item) {
if (item->showNotification()) {
destroyUnreadBar();
if (markingMessagesRead()) {
if (_list && item->hasUnwatchedEffect()) {
_list->startEffectOnRead(item);
}
if (item->isUnreadMention() && !item->isUnreadMedia()) {
session().api().markContentsRead(item);
}