From 10f65c63e7f6aa3ef08f174b29f3fbfe68e035c3 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 14 Jul 2023 12:02:04 +0400 Subject: [PATCH] Allow opening unknown stories from chats list. --- Telegram/SourceFiles/data/data_stories.cpp | 22 +++++++++++++++---- Telegram/SourceFiles/data/data_stories.h | 8 +++++-- .../window/window_session_controller.cpp | 13 +++++++++-- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/data/data_stories.cpp b/Telegram/SourceFiles/data/data_stories.cpp index 19ff73eb29..20db4a13a2 100644 --- a/Telegram/SourceFiles/data/data_stories.cpp +++ b/Telegram/SourceFiles/data/data_stories.cpp @@ -196,21 +196,34 @@ Story *Stories::applyFromWebpage(PeerId peerId, const MTPstoryItem &story) { return value ? value->get() : nullptr; } -void Stories::requestUserStories(not_null user) { - if (!_requestingUserStories.emplace(user).second) { +void Stories::requestUserStories( + not_null user, + Fn done) { + const auto [i, ok] = _requestingUserStories.emplace(user); + if (done) { + i->second.push_back(std::move(done)); + } + if (!ok) { return; } + const auto finish = [=] { + if (const auto callbacks = _requestingUserStories.take(user)) { + for (const auto &callback : *callbacks) { + callback(); + } + } + }; _owner->session().api().request(MTPstories_GetUserStories( user->inputUser )).done([=](const MTPstories_UserStories &result) { - _requestingUserStories.remove(user); const auto &data = result.data(); _owner->processUsers(data.vusers()); parseAndApply(data.vstories()); + finish(); }).fail([=] { - _requestingUserStories.remove(user); applyDeletedFromSources(user->id, StorySourcesList::NotHidden); applyDeletedFromSources(user->id, StorySourcesList::Hidden); + finish(); }).send(); } @@ -290,6 +303,7 @@ void Stories::parseAndApply(const MTPUserStories &stories) { if (result.ids.empty()) { applyDeletedFromSources(peerId, StorySourcesList::NotHidden); applyDeletedFromSources(peerId, StorySourcesList::Hidden); + user->setStoriesState(UserData::StoriesState::None); return; } else if (user->isSelf()) { result.readTill = result.ids.back().id; diff --git a/Telegram/SourceFiles/data/data_stories.h b/Telegram/SourceFiles/data/data_stories.h index 2bdd27d1c5..848227a5d6 100644 --- a/Telegram/SourceFiles/data/data_stories.h +++ b/Telegram/SourceFiles/data/data_stories.h @@ -218,6 +218,9 @@ public: bool registerPolling(FullStoryId id, Polling polling); void unregisterPolling(FullStoryId id, Polling polling); + void requestUserStories( + not_null user, + Fn done = nullptr); void savedStateChanged(not_null story); [[nodiscard]] std::shared_ptr lookupItem( @@ -266,7 +269,6 @@ private: void sendIncrementViewsRequests(); void checkQuitPreventFinished(); - void requestUserStories(not_null user); void registerExpiring(TimeId expires, FullStoryId id); void scheduleExpireTimer(); void processExpired(); @@ -335,7 +337,9 @@ private: base::flat_set _markReadPending; base::Timer _markReadTimer; base::flat_set _markReadRequests; - base::flat_set> _requestingUserStories; + base::flat_map< + not_null, + std::vector>> _requestingUserStories; base::flat_map> _incrementViewsPending; base::Timer _incrementViewsTimer; diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index e35e83d038..1a89da1b1c 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -2528,9 +2528,10 @@ void SessionController::openPeerStory( if (from) { window().openInMediaView(OpenRequest(this, *from, context)); } else if (from.error() == Data::NoStory::Unknown) { - stories.resolve({ peer->id, storyId }, crl::guard(&_storyOpenGuard, [=] { + const auto done = crl::guard(&_storyOpenGuard, [=] { openPeerStory(peer, storyId, context); - })); + }); + stories.resolve({ peer->id, storyId }, done); } } @@ -2540,6 +2541,7 @@ void SessionController::openPeerStories( using namespace Media::View; using namespace Data; + invalidate_weak_ptrs(&_storyOpenGuard); auto &stories = session().data().stories(); if (const auto source = stories.source(peerId)) { if (const auto idDates = source->toOpen()) { @@ -2550,6 +2552,13 @@ void SessionController::openPeerStories( ? StoriesContext{ *list } : StoriesContext{ StoriesContextPeer() })); } + } else if (const auto userId = peerToUser(peerId)) { + if (const auto user = session().data().userLoaded(userId)) { + const auto done = crl::guard(&_storyOpenGuard, [=] { + openPeerStories(peerId, list); + }); + stories.requestUserStories(user, done); + } } }