In the viewer remember which story was opened.

This commit is contained in:
John Preston 2023-07-21 18:49:54 +04:00
parent c0b7577db9
commit e7312697bf
4 changed files with 75 additions and 28 deletions

View File

@ -673,6 +673,7 @@ void Controller::rebuildFromContext(
_showingUnreadSources = source && (source->readTill < id);
}
rebuildCachedSourcesList(sources, (i - begin(sources)));
_cachedSourcesList[_cachedSourceIndex].shownId = storyId.story;
showSiblings(&user->session());
if (int(sources.end() - i) < kPreloadUsersCount) {
stories.loadMore(list);
@ -980,13 +981,13 @@ void Controller::showSiblings(not_null<Main::Session*> session) {
session,
(_cachedSourceIndex > 0
? _cachedSourcesList[_cachedSourceIndex - 1]
: PeerId()));
: CachedSource()));
showSibling(
_siblingRight,
session,
(_cachedSourceIndex + 1 < _cachedSourcesList.size()
? _cachedSourcesList[_cachedSourceIndex + 1]
: PeerId()));
: CachedSource()));
}
void Controller::hideSiblings() {
@ -997,16 +998,16 @@ void Controller::hideSiblings() {
void Controller::showSibling(
std::unique_ptr<Sibling> &sibling,
not_null<Main::Session*> session,
PeerId peerId) {
if (!peerId) {
CachedSource cached) {
if (!cached) {
sibling = nullptr;
return;
}
const auto source = session->data().stories().source(peerId);
const auto source = session->data().stories().source(cached.peerId);
if (!source) {
sibling = nullptr;
} else if (!sibling || !sibling->shows(*source)) {
sibling = std::make_unique<Sibling>(this, *source);
} else if (!sibling || !sibling->shows(*source, cached.shownId)) {
sibling = std::make_unique<Sibling>(this, *source, cached.shownId);
}
}
@ -1301,12 +1302,18 @@ void Controller::rebuildCachedSourcesList(
// Remove removed.
_cachedSourcesList.erase(ranges::remove_if(_cachedSourcesList, [&](
PeerId id) {
return !ranges::contains(lists, id, &Data::StoriesSourceInfo::id);
CachedSource source) {
return !ranges::contains(
lists,
source.peerId,
&Data::StoriesSourceInfo::id);
}), end(_cachedSourcesList));
// Find current, full rebuild if can't find.
const auto i = ranges::find(_cachedSourcesList, currentPeerId);
const auto i = ranges::find(
_cachedSourcesList,
currentPeerId,
&CachedSource::peerId);
if (i == end(_cachedSourcesList)) {
_cachedSourcesList.clear();
} else {
@ -1320,17 +1327,24 @@ void Controller::rebuildCachedSourcesList(
|| (info.unreadCount > 0)
|| (info.id == currentPeerId);
};
const auto mapper = [](const Data::StoriesSourceInfo &info) {
return CachedSource{ info.id };
};
_cachedSourcesList = lists
| ranges::views::filter(predicate)
| ranges::views::transform(&Data::StoriesSourceInfo::id)
| ranges::views::transform(mapper)
| ranges::to_vector;
_cachedSourceIndex = ranges::find(_cachedSourcesList, currentPeerId)
- begin(_cachedSourcesList);
_cachedSourceIndex = ranges::find(
_cachedSourcesList,
currentPeerId,
&CachedSource::peerId
) - begin(_cachedSourcesList);
} else if (ranges::equal(
lists,
_cachedSourcesList,
ranges::equal_to(),
&Data::StoriesSourceInfo::id)) {
&Data::StoriesSourceInfo::id,
&CachedSource::peerId)) {
// No rebuild needed.
} else {
// All that go before the current push to front.
@ -1338,10 +1352,13 @@ void Controller::rebuildCachedSourcesList(
const auto &info = lists[--before];
if (_showingUnreadSources && !info.unreadCount) {
continue;
} else if (!ranges::contains(_cachedSourcesList, info.id)) {
} else if (!ranges::contains(
_cachedSourcesList,
info.id,
&CachedSource::peerId)) {
_cachedSourcesList.insert(
begin(_cachedSourcesList),
info.id);
{ info.id });
++_cachedSourceIndex;
}
}
@ -1352,8 +1369,11 @@ void Controller::rebuildCachedSourcesList(
const auto &info = lists[after];
if (_showingUnreadSources && !info.unreadCount) {
continue;
} else if (!ranges::contains(_cachedSourcesList, info.id)) {
_cachedSourcesList.push_back(info.id);
} else if (!ranges::contains(
_cachedSourcesList,
info.id,
&CachedSource::peerId)) {
_cachedSourcesList.push_back({ info.id });
}
}
}

View File

@ -177,6 +177,14 @@ private:
const StoriesList &,
const StoriesList &) = default;
};
struct CachedSource {
PeerId peerId = 0;
StoryId shownId = 0;
explicit operator bool() const {
return peerId != 0;
}
};
class PhotoPlayback;
class Unsupported;
@ -198,7 +206,7 @@ private:
void showSibling(
std::unique_ptr<Sibling> &sibling,
not_null<Main::Session*> session,
PeerId peerId);
CachedSource cached);
void subjumpTo(int index);
void checkWaitingFor();
@ -264,7 +272,7 @@ private:
bool _started = false;
bool _viewed = false;
std::vector<PeerId> _cachedSourcesList;
std::vector<CachedSource> _cachedSourcesList;
int _cachedSourceIndex = -1;
bool _showingUnreadSources = false;

View File

@ -33,6 +33,17 @@ constexpr auto kSiblingFadeOver = 0.4;
constexpr auto kSiblingNameOpacity = 0.8;
constexpr auto kSiblingNameOpacityOver = 1.;
[[nodiscard]] StoryId LookupShownId(
const Data::StoriesSource &source,
StoryId suggestedId) {
const auto i = suggestedId
? source.ids.lower_bound(Data::StoryIdDates{ suggestedId })
: end(source.ids);
return (i != end(source.ids) && i->id == suggestedId)
? suggestedId
: source.toOpen().id;
}
} // namespace
class Sibling::Loader {
@ -229,9 +240,10 @@ bool Sibling::LoaderVideo::updateAfterGoodCheck() {
Sibling::Sibling(
not_null<Controller*> controller,
const Data::StoriesSource &source)
const Data::StoriesSource &source,
StoryId suggestedId)
: _controller(controller)
, _id{ source.user->id, source.ids.front().id }
, _id{ source.user->id, LookupShownId(source, suggestedId) }
, _peer(source.user) {
checkStory();
_goodShown.stop();
@ -288,10 +300,14 @@ not_null<PeerData*> Sibling::peer() const {
return _peer;
}
bool Sibling::shows(const Data::StoriesSource &source) const {
Expects(!source.ids.empty());
return _id == FullStoryId{ source.user->id, source.ids.front().id };
bool Sibling::shows(
const Data::StoriesSource &source,
StoryId suggestedId) const {
const auto fullId = FullStoryId{
source.user->id,
LookupShownId(source, suggestedId),
};
return (_id == fullId);
}
SiblingView Sibling::view(const SiblingLayout &layout, float64 over) {

View File

@ -26,12 +26,15 @@ class Sibling final : public base::has_weak_ptr {
public:
Sibling(
not_null<Controller*> controller,
const Data::StoriesSource &source);
const Data::StoriesSource &source,
StoryId suggestedId);
~Sibling();
[[nodiscard]] FullStoryId shownId() const;
[[nodiscard]] not_null<PeerData*> peer() const;
[[nodiscard]] bool shows(const Data::StoriesSource &source) const;
[[nodiscard]] bool shows(
const Data::StoriesSource &source,
StoryId suggestedId) const;
[[nodiscard]] SiblingView view(
const SiblingLayout &layout,