Send views for expired pinned stories.

This commit is contained in:
John Preston 2023-06-09 18:49:09 +04:00
parent 10d64d6bdf
commit af5228771c
4 changed files with 83 additions and 8 deletions

View File

@ -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<Session*> 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<MTPint>();
auto peer = PeerId();
struct Prepared {
PeerId peer = 0;
QVector<MTPint> ids;
};
auto prepared = std::vector<Prepared>();
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<MTPint>(std::move(ids))
)).done(finish).fail(finish).send();
_incrementViewsPending.remove(peer);
}
}
void Stories::loadViewsSlice(
StoryId id,
std::optional<StoryView> 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..."));

View File

@ -281,6 +281,8 @@ private:
void sendMarkAsReadRequests();
void sendMarkAsReadRequest(not_null<PeerData*> peer, StoryId tillId);
void sendIncrementViewsRequests();
void checkQuitPreventFinished();
void requestUserStories(not_null<UserData*> user);
void addToArchive(not_null<Story*> story);
@ -337,6 +339,10 @@ private:
base::flat_set<PeerId> _markReadRequests;
base::flat_set<not_null<UserData*>> _requestingUserStories;
base::flat_map<PeerId, base::flat_set<StoryId>> _incrementViewsPending;
base::Timer _incrementViewsTimer;
base::flat_set<PeerId> _incrementViewsRequests;
StoryId _viewsStoryId = 0;
std::optional<StoryView> _viewsOffset;
Fn<void(std::vector<StoryView>)> _viewsDone;

View File

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

View File

@ -195,6 +195,7 @@ private:
FullStoryId _waitingForId;
int _index = 0;
bool _started = false;
bool _viewed = false;
ViewsSlice _viewsSlice;
rpl::event_stream<> _moreViewsLoaded;