From af5228771cd96ca4168cab2ce0ce04701ea86895 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 9 Jun 2023 18:49:09 +0400 Subject: [PATCH] Send views for expired pinned stories. --- Telegram/SourceFiles/data/data_stories.cpp | 79 +++++++++++++++++-- Telegram/SourceFiles/data/data_stories.h | 6 ++ .../stories/media_stories_controller.cpp | 5 ++ .../media/stories/media_stories_controller.h | 1 + 4 files changed, 83 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/data/data_stories.cpp b/Telegram/SourceFiles/data/data_stories.cpp index c1b08a657..5a51f0360 100644 --- a/Telegram/SourceFiles/data/data_stories.cpp +++ b/Telegram/SourceFiles/data/data_stories.cpp @@ -33,6 +33,7 @@ constexpr auto kMaxResolveTogether = 100; constexpr auto kIgnorePreloadAroundIfLoaded = 15; constexpr auto kPreloadAroundCount = 30; constexpr auto kMarkAsReadDelay = 3 * crl::time(1000); +constexpr auto kIncrementViewsDelay = 5 * crl::time(1000); constexpr auto kArchiveFirstPerPage = 30; constexpr auto kArchivePerPage = 100; constexpr auto kSavedFirstPerPage = 30; @@ -296,7 +297,8 @@ bool Story::applyChanges(StoryMedia media, const MTPDstoryItem &data) { Stories::Stories(not_null owner) : _owner(owner) , _expireTimer([=] { processExpired(); }) -, _markReadTimer([=] { sendMarkAsReadRequests(); }) { +, _markReadTimer([=] { sendMarkAsReadRequests(); }) +, _incrementViewsTimer([=] { sendIncrementViewsRequests(); }) { } Stories::~Stories() { @@ -1082,6 +1084,20 @@ void Stories::loadAround(FullStoryId id, StoriesContext context) { } void Stories::markAsRead(FullStoryId id, bool viewed) { + if (id.peer == _owner->session().userPeerId()) { + return; + } + const auto maybeStory = lookup(id); + if (!maybeStory) { + return; + } + const auto story = *maybeStory; + if (story->expired() && story->pinned()) { + _incrementViewsPending[id.peer].emplace(id.story); + if (!_incrementViewsTimer.isActive()) { + _incrementViewsTimer.callOnce(kIncrementViewsDelay); + } + } const auto i = _all.find(id.peer); Assert(i != end(_all)); if (i->second.readTill >= id.story) { @@ -1176,12 +1192,7 @@ void Stories::sendMarkAsReadRequest( && _markReadPending.contains(peerId)) { sendMarkAsReadRequests(); } - if (_markReadRequests.empty()) { - if (Core::Quitting()) { - LOG(("Stories doesn't prevent quit any more.")); - } - Core::App().quitPreventFinished(); - } + checkQuitPreventFinished(); }; const auto api = &_owner->session().api(); @@ -1191,6 +1202,15 @@ void Stories::sendMarkAsReadRequest( )).done(finish).fail(finish).send(); } +void Stories::checkQuitPreventFinished() { + if (_markReadRequests.empty() && _incrementViewsRequests.empty()) { + if (Core::Quitting()) { + LOG(("Stories doesn't prevent quit any more.")); + } + Core::App().quitPreventFinished(); + } +} + void Stories::sendMarkAsReadRequests() { _markReadTimer.cancel(); for (auto i = begin(_markReadPending); i != end(_markReadPending);) { @@ -1207,6 +1227,46 @@ void Stories::sendMarkAsReadRequests() { } } +void Stories::sendIncrementViewsRequests() { + if (_incrementViewsPending.empty()) { + return; + } + auto ids = QVector(); + auto peer = PeerId(); + struct Prepared { + PeerId peer = 0; + QVector ids; + }; + auto prepared = std::vector(); + for (const auto &[peer, ids] : _incrementViewsPending) { + if (_incrementViewsRequests.contains(peer)) { + continue; + } + prepared.push_back({ .peer = peer }); + for (const auto &id : ids) { + prepared.back().ids.push_back(MTP_int(id)); + } + } + + const auto api = &_owner->session().api(); + for (auto &[peer, ids] : prepared) { + _incrementViewsRequests.emplace(peer); + const auto finish = [=] { + _incrementViewsRequests.remove(peer); + if (!_incrementViewsTimer.isActive() + && _incrementViewsPending.contains(peer)) { + sendIncrementViewsRequests(); + } + checkQuitPreventFinished(); + }; + api->request(MTPstories_IncrementStoryViews( + _owner->peer(peer)->asUser()->inputUser, + MTP_vector(std::move(ids)) + )).done(finish).fail(finish).send(); + _incrementViewsPending.remove(peer); + } +} + void Stories::loadViewsSlice( StoryId id, std::optional offset, @@ -1392,7 +1452,10 @@ bool Stories::isQuitPrevent() { if (!_markReadPending.empty()) { sendMarkAsReadRequests(); } - if (_markReadRequests.empty()) { + if (!_incrementViewsPending.empty()) { + sendIncrementViewsRequests(); + } + if (_markReadRequests.empty() && _incrementViewsRequests.empty()) { return false; } LOG(("Stories prevents quit, marking as read...")); diff --git a/Telegram/SourceFiles/data/data_stories.h b/Telegram/SourceFiles/data/data_stories.h index a94b6ef12..9cde3d245 100644 --- a/Telegram/SourceFiles/data/data_stories.h +++ b/Telegram/SourceFiles/data/data_stories.h @@ -281,6 +281,8 @@ private: void sendMarkAsReadRequests(); void sendMarkAsReadRequest(not_null peer, StoryId tillId); + void sendIncrementViewsRequests(); + void checkQuitPreventFinished(); void requestUserStories(not_null user); void addToArchive(not_null story); @@ -337,6 +339,10 @@ private: base::flat_set _markReadRequests; base::flat_set> _requestingUserStories; + base::flat_map> _incrementViewsPending; + base::Timer _incrementViewsTimer; + base::flat_set _incrementViewsRequests; + StoryId _viewsStoryId = 0; std::optional _viewsOffset; Fn)> _viewsDone; diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp index 9131724f2..8889204d9 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp @@ -490,6 +490,7 @@ void Controller::show( return; } _shown = storyId; + _viewed = false; _captionText = story->caption(); _captionFullView = nullptr; invalidate_weak_ptrs(&_viewsLoadGuard); @@ -633,6 +634,10 @@ void Controller::maybeMarkAsRead(const Player::TrackState &state) { void Controller::markAsRead() { Expects(_source.has_value()); + if (_viewed) { + return; + } + _viewed = true; _source->user->owner().stories().markAsRead(_shown, _started); } diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.h b/Telegram/SourceFiles/media/stories/media_stories_controller.h index f59cb0f36..52d780093 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.h +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.h @@ -195,6 +195,7 @@ private: FullStoryId _waitingForId; int _index = 0; bool _started = false; + bool _viewed = false; ViewsSlice _viewsSlice; rpl::event_stream<> _moreViewsLoaded;