Cache stories sources order in viewer.

This commit is contained in:
John Preston 2023-06-21 13:35:10 +04:00
parent 4e39144d0f
commit ebafb55b1b
2 changed files with 78 additions and 11 deletions

View File

@ -618,7 +618,8 @@ void Controller::rebuildFromContext(
storyId.peer,
&StoriesSourceInfo::id);
if (i != end(sources)) {
showSiblings(&user->session(), sources, (i - begin(sources)));
rebuildCachedSourcesList(sources, (i - begin(sources)));
showSiblings(&user->session());
if (int(sources.end() - i) < kPreloadUsersCount) {
stories.loadMore(list);
}
@ -780,18 +781,19 @@ void Controller::setPlayingAllowed(bool allowed) {
}
}
void Controller::showSiblings(
not_null<Main::Session*> session,
const std::vector<Data::StoriesSourceInfo> &sources,
int index) {
void Controller::showSiblings(not_null<Main::Session*> session) {
showSibling(
_siblingLeft,
session,
(index > 0) ? sources[index - 1].id : PeerId());
(_cachedSourceIndex > 0
? _cachedSourcesList[_cachedSourceIndex - 1]
: PeerId()));
showSibling(
_siblingRight,
session,
(index + 1 < sources.size()) ? sources[index + 1].id : PeerId());
(_cachedSourceIndex + 1 < _cachedSourcesList.size()
? _cachedSourcesList[_cachedSourceIndex + 1]
: PeerId()));
}
void Controller::hideSiblings() {
@ -1116,6 +1118,68 @@ void Controller::loadMoreToList() {
});
}
void Controller::rebuildCachedSourcesList(
const std::vector<Data::StoriesSourceInfo> &lists,
int index) {
Expects(index >= 0 && index < lists.size());
// Remove removed.
_cachedSourcesList.erase(ranges::remove_if(_cachedSourcesList, [&](
PeerId id) {
return !ranges::contains(lists, id, &Data::StoriesSourceInfo::id);
}), end(_cachedSourcesList));
// Find current, full rebuild if can't find.
const auto i = ranges::find(_cachedSourcesList, lists[index].id);
if (i == end(_cachedSourcesList)) {
_cachedSourcesList.clear();
} else {
_cachedSourceIndex = int(i - begin(_cachedSourcesList));
}
if (_cachedSourcesList.empty()) {
// Full rebuild.
_cachedSourcesList = lists
| ranges::views::transform(&Data::StoriesSourceInfo::id)
| ranges::to_vector;
_cachedSourceIndex = index;
} else if (ranges::equal(
lists,
_cachedSourcesList,
ranges::equal_to(),
&Data::StoriesSourceInfo::id)) {
// No rebuild needed.
_cachedSourceIndex = index;
} else {
// All that go before the current push to front.
for (auto before = index; before > 0;) {
--before;
const auto peerId = lists[--before].id;
if (!ranges::contains(_cachedSourcesList, peerId)) {
_cachedSourcesList.insert(
begin(_cachedSourcesList),
peerId);
++_cachedSourceIndex;
}
}
// All that go after the current push to back.
for (auto after = index + 1, count = int(lists.size()); after != count; ++after) {
const auto peerId = lists[after].id;
if (!ranges::contains(_cachedSourcesList, peerId)) {
_cachedSourcesList.push_back(peerId);
}
}
}
Ensures(_cachedSourcesList.size() == lists.size());
Ensures(ranges::equal(
lists,
_cachedSourcesList,
ranges::equal_to(),
&Data::StoriesSourceInfo::id));
Ensures(_cachedSourceIndex >= 0 && _cachedSourceIndex < _cachedSourcesList.size());
}
void Controller::refreshViewsFromData() {
Expects(shown());

View File

@ -162,10 +162,7 @@ private:
void setPlayingAllowed(bool allowed);
void hideSiblings();
void showSiblings(
not_null<Main::Session*> session,
const std::vector<Data::StoriesSourceInfo> &lists,
int index);
void showSiblings(not_null<Main::Session*> session);
void showSibling(
std::unique_ptr<Sibling> &sibling,
not_null<Main::Session*> session,
@ -186,6 +183,9 @@ private:
void rebuildFromContext(not_null<UserData*> user, FullStoryId storyId);
void checkMoveByDelta();
void loadMoreToList();
void rebuildCachedSourcesList(
const std::vector<Data::StoriesSourceInfo> &lists,
int index);
void startReactionAnimation(
Data::ReactionId id,
@ -227,6 +227,9 @@ private:
bool _started = false;
bool _viewed = false;
std::vector<PeerId> _cachedSourcesList;
int _cachedSourceIndex = -1;
ViewsSlice _viewsSlice;
rpl::event_stream<> _moreViewsLoaded;
base::has_weak_ptr _viewsLoadGuard;