Update API scheme on layer 161.
This commit is contained in:
		
							parent
							
								
									6be1a05876
								
							
						
					
					
						commit
						318d75cc63
					
				
					 8 changed files with 100 additions and 146 deletions
				
			
		| 
						 | 
				
			
			@ -862,7 +862,8 @@ void Stories::activateStealthMode(Fn<void()> done) {
 | 
			
		|||
	using Flag = MTPstories_ActivateStealthMode::Flag;
 | 
			
		||||
	api->request(MTPstories_ActivateStealthMode(
 | 
			
		||||
		MTP_flags(Flag::f_past | Flag::f_future)
 | 
			
		||||
	)).done([=](const MTPBool &result) {
 | 
			
		||||
	)).done([=](const MTPUpdates &result) {
 | 
			
		||||
		api->applyUpdates(result);
 | 
			
		||||
		if (done) done();
 | 
			
		||||
	}).fail([=] {
 | 
			
		||||
		if (done) done();
 | 
			
		||||
| 
						 | 
				
			
			@ -1233,11 +1234,11 @@ void Stories::sendIncrementViewsRequests() {
 | 
			
		|||
 | 
			
		||||
void Stories::loadViewsSlice(
 | 
			
		||||
		StoryId id,
 | 
			
		||||
		std::optional<StoryView> offset,
 | 
			
		||||
		Fn<void(std::vector<StoryView>)> done) {
 | 
			
		||||
		QString offset,
 | 
			
		||||
		Fn<void(StoryViews)> done) {
 | 
			
		||||
	if (_viewsStoryId == id
 | 
			
		||||
		&& _viewsOffset == offset
 | 
			
		||||
		&& (offset || _viewsRequestId)) {
 | 
			
		||||
		&& (!offset.isEmpty() || _viewsRequestId)) {
 | 
			
		||||
		if (_viewsRequestId) {
 | 
			
		||||
			_viewsDone = std::move(done);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1251,21 +1252,27 @@ void Stories::loadViewsSlice(
 | 
			
		|||
	const auto perPage = _viewsDone ? kViewsPerPage : kPollingViewsPerPage;
 | 
			
		||||
	api->request(_viewsRequestId).cancel();
 | 
			
		||||
	_viewsRequestId = api->request(MTPstories_GetStoryViewsList(
 | 
			
		||||
		MTP_flags(0),
 | 
			
		||||
		MTPstring(), // q
 | 
			
		||||
		MTP_int(id),
 | 
			
		||||
		MTP_int(offset ? offset->date : 0),
 | 
			
		||||
		MTP_long(offset ? peerToUser(offset->peer->id).bare : 0),
 | 
			
		||||
		MTP_string(offset),
 | 
			
		||||
		MTP_int(perPage)
 | 
			
		||||
	)).done([=](const MTPstories_StoryViewsList &result) {
 | 
			
		||||
		_viewsRequestId = 0;
 | 
			
		||||
 | 
			
		||||
		auto slice = std::vector<StoryView>();
 | 
			
		||||
 | 
			
		||||
		const auto &data = result.data();
 | 
			
		||||
		auto slice = StoryViews{
 | 
			
		||||
			.nextOffset = data.vnext_offset().value_or_empty(),
 | 
			
		||||
			.total = data.vcount().v,
 | 
			
		||||
		};
 | 
			
		||||
		_owner->processUsers(data.vusers());
 | 
			
		||||
		slice.reserve(data.vviews().v.size());
 | 
			
		||||
		slice.list.reserve(data.vviews().v.size());
 | 
			
		||||
		for (const auto &view : data.vviews().v) {
 | 
			
		||||
			slice.push_back({
 | 
			
		||||
			slice.list.push_back({
 | 
			
		||||
				.peer = _owner->peer(peerFromUser(view.data().vuser_id())),
 | 
			
		||||
				.reaction = (view.data().vreaction()
 | 
			
		||||
					? ReactionFromMTP(*view.data().vreaction())
 | 
			
		||||
					: Data::ReactionId()),
 | 
			
		||||
				.date = view.data().vdate().v,
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1274,7 +1281,7 @@ void Stories::loadViewsSlice(
 | 
			
		|||
			.story = _viewsStoryId,
 | 
			
		||||
		};
 | 
			
		||||
		if (const auto story = lookup(fullId)) {
 | 
			
		||||
			(*story)->applyViewsSlice(_viewsOffset, slice, data.vcount().v);
 | 
			
		||||
			(*story)->applyViewsSlice(_viewsOffset, slice);
 | 
			
		||||
		}
 | 
			
		||||
		if (const auto done = base::take(_viewsDone)) {
 | 
			
		||||
			done(std::move(slice));
 | 
			
		||||
| 
						 | 
				
			
			@ -1713,7 +1720,7 @@ void Stories::sendPollingViewsRequests() {
 | 
			
		|||
		return;
 | 
			
		||||
	} else if (!_viewsRequestId) {
 | 
			
		||||
		Assert(_viewsDone == nullptr);
 | 
			
		||||
		loadViewsSlice(_pollingViews.front()->id(), std::nullopt, nullptr);
 | 
			
		||||
		loadViewsSlice(_pollingViews.front()->id(), QString(), nullptr);
 | 
			
		||||
	}
 | 
			
		||||
	_pollingViewsTimer.callOnce(kPollViewsInterval);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -179,8 +179,8 @@ public:
 | 
			
		|||
	static constexpr auto kViewsPerPage = 50;
 | 
			
		||||
	void loadViewsSlice(
 | 
			
		||||
		StoryId id,
 | 
			
		||||
		std::optional<StoryView> offset,
 | 
			
		||||
		Fn<void(std::vector<StoryView>)> done);
 | 
			
		||||
		QString offset,
 | 
			
		||||
		Fn<void(StoryViews)> done);
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] const StoriesIds &archive() const;
 | 
			
		||||
	[[nodiscard]] rpl::producer<> archiveChanged() const;
 | 
			
		||||
| 
						 | 
				
			
			@ -366,8 +366,8 @@ private:
 | 
			
		|||
	base::flat_set<PeerId> _incrementViewsRequests;
 | 
			
		||||
 | 
			
		||||
	StoryId _viewsStoryId = 0;
 | 
			
		||||
	std::optional<StoryView> _viewsOffset;
 | 
			
		||||
	Fn<void(std::vector<StoryView>)> _viewsDone;
 | 
			
		||||
	QString _viewsOffset;
 | 
			
		||||
	Fn<void(StoryViews)> _viewsDone;
 | 
			
		||||
	mtpRequestId _viewsRequestId = 0;
 | 
			
		||||
 | 
			
		||||
	base::flat_set<FullStoryId> _preloaded;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -339,51 +339,35 @@ const std::vector<not_null<PeerData*>> &Story::recentViewers() const {
 | 
			
		|||
	return _recentViewers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::vector<StoryView> &Story::viewsList() const {
 | 
			
		||||
	return _viewsList;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Story::views() const {
 | 
			
		||||
const StoryViews &Story::viewsList() const {
 | 
			
		||||
	return _views;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Story::views() const {
 | 
			
		||||
	return _views.total;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Story::applyViewsSlice(
 | 
			
		||||
		const std::optional<StoryView> &offset,
 | 
			
		||||
		const std::vector<StoryView> &slice,
 | 
			
		||||
		int total) {
 | 
			
		||||
	const auto changed = (_views != total);
 | 
			
		||||
	_views = total;
 | 
			
		||||
	if (!offset) {
 | 
			
		||||
		const auto i = _viewsList.empty()
 | 
			
		||||
			? end(slice)
 | 
			
		||||
			: ranges::find(slice, _viewsList.front());
 | 
			
		||||
		const auto merge = (i != end(slice))
 | 
			
		||||
			&& !ranges::contains(slice, _viewsList.back());
 | 
			
		||||
		if (merge) {
 | 
			
		||||
			_viewsList.insert(begin(_viewsList), begin(slice), i);
 | 
			
		||||
		} else {
 | 
			
		||||
			_viewsList = slice;
 | 
			
		||||
		}
 | 
			
		||||
	} else if (!slice.empty()) {
 | 
			
		||||
		const auto i = ranges::find(_viewsList, *offset);
 | 
			
		||||
		const auto merge = (i != end(_viewsList))
 | 
			
		||||
			&& !ranges::contains(_viewsList, slice.back());
 | 
			
		||||
		if (merge) {
 | 
			
		||||
			const auto after = i + 1;
 | 
			
		||||
			if (after == end(_viewsList)) {
 | 
			
		||||
				_viewsList.insert(after, begin(slice), end(slice));
 | 
			
		||||
			} else {
 | 
			
		||||
				const auto j = ranges::find(slice, _viewsList.back());
 | 
			
		||||
				if (j != end(slice)) {
 | 
			
		||||
					_viewsList.insert(end(_viewsList), j + 1, end(slice));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		const QString &offset,
 | 
			
		||||
		const StoryViews &slice) {
 | 
			
		||||
	const auto changed = (_views.total != slice.total);
 | 
			
		||||
	_views.total = slice.total;
 | 
			
		||||
	if (offset.isEmpty()) {
 | 
			
		||||
		_views = slice;
 | 
			
		||||
	} else if (_views.nextOffset == offset) {
 | 
			
		||||
		_views.list.insert(
 | 
			
		||||
			end(_views.list),
 | 
			
		||||
			begin(slice.list),
 | 
			
		||||
			end(slice.list));
 | 
			
		||||
		_views.nextOffset = slice.nextOffset;
 | 
			
		||||
		if (_views.nextOffset.isEmpty()) {
 | 
			
		||||
			_views.total = int(_views.list.size());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	const auto known = int(_viewsList.size());
 | 
			
		||||
	const auto known = int(_views.list.size());
 | 
			
		||||
	if (known >= _recentViewers.size()) {
 | 
			
		||||
		const auto take = std::min(known, kRecentViewersMax);
 | 
			
		||||
		auto viewers = _viewsList
 | 
			
		||||
		auto viewers = _views.list
 | 
			
		||||
			| ranges::views::take(take)
 | 
			
		||||
			| ranges::views::transform(&StoryView::peer)
 | 
			
		||||
			| ranges::to_vector;
 | 
			
		||||
| 
						 | 
				
			
			@ -436,7 +420,7 @@ void Story::applyFields(
 | 
			
		|||
			&owner().session(),
 | 
			
		||||
			data.ventities().value_or_empty()),
 | 
			
		||||
	};
 | 
			
		||||
	auto views = _views;
 | 
			
		||||
	auto views = _views.total;
 | 
			
		||||
	auto viewers = std::vector<not_null<PeerData*>>();
 | 
			
		||||
	if (!data.is_min()) {
 | 
			
		||||
		if (const auto info = data.vviews()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -457,7 +441,7 @@ void Story::applyFields(
 | 
			
		|||
	const auto editedChanged = (_edited != edited);
 | 
			
		||||
	const auto mediaChanged = (_media != media);
 | 
			
		||||
	const auto captionChanged = (_caption != caption);
 | 
			
		||||
	const auto viewsChanged = (_views != views)
 | 
			
		||||
	const auto viewsChanged = (_views.total != views)
 | 
			
		||||
		|| (_recentViewers != viewers);
 | 
			
		||||
 | 
			
		||||
	_privacyPublic = (privacy == StoryPrivacy::Public);
 | 
			
		||||
| 
						 | 
				
			
			@ -468,8 +452,10 @@ void Story::applyFields(
 | 
			
		|||
	_edited = edited;
 | 
			
		||||
	_pinned = pinned;
 | 
			
		||||
	_noForwards = noForwards;
 | 
			
		||||
	if (_views.total != views) {
 | 
			
		||||
		_views = StoryViews{ .total = views };
 | 
			
		||||
	}
 | 
			
		||||
	if (viewsChanged) {
 | 
			
		||||
		_views = views;
 | 
			
		||||
		_recentViewers = std::move(viewers);
 | 
			
		||||
	}
 | 
			
		||||
	if (mediaChanged) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "base/weak_ptr.h"
 | 
			
		||||
#include "data/data_message_reaction_id.h"
 | 
			
		||||
 | 
			
		||||
class Image;
 | 
			
		||||
class PhotoData;
 | 
			
		||||
| 
						 | 
				
			
			@ -58,11 +59,18 @@ struct StoryMedia {
 | 
			
		|||
 | 
			
		||||
struct StoryView {
 | 
			
		||||
	not_null<PeerData*> peer;
 | 
			
		||||
	Data::ReactionId reaction;
 | 
			
		||||
	TimeId date = 0;
 | 
			
		||||
 | 
			
		||||
	friend inline bool operator==(StoryView, StoryView) = default;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct StoryViews {
 | 
			
		||||
	std::vector<StoryView> list;
 | 
			
		||||
	QString nextOffset;
 | 
			
		||||
	int total = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Story final {
 | 
			
		||||
public:
 | 
			
		||||
	Story(
 | 
			
		||||
| 
						 | 
				
			
			@ -115,12 +123,9 @@ public:
 | 
			
		|||
 | 
			
		||||
	[[nodiscard]] auto recentViewers() const
 | 
			
		||||
		-> const std::vector<not_null<PeerData*>> &;
 | 
			
		||||
	[[nodiscard]] const std::vector<StoryView> &viewsList() const;
 | 
			
		||||
	[[nodiscard]] const StoryViews &viewsList() const;
 | 
			
		||||
	[[nodiscard]] int views() const;
 | 
			
		||||
	void applyViewsSlice(
 | 
			
		||||
		const std::optional<StoryView> &offset,
 | 
			
		||||
		const std::vector<StoryView> &slice,
 | 
			
		||||
		int total);
 | 
			
		||||
	void applyViewsSlice(const QString &offset, const StoryViews &slice);
 | 
			
		||||
 | 
			
		||||
	void applyChanges(
 | 
			
		||||
		StoryMedia media,
 | 
			
		||||
| 
						 | 
				
			
			@ -140,8 +145,7 @@ private:
 | 
			
		|||
	StoryMedia _media;
 | 
			
		||||
	TextWithEntities _caption;
 | 
			
		||||
	std::vector<not_null<PeerData*>> _recentViewers;
 | 
			
		||||
	std::vector<StoryView> _viewsList;
 | 
			
		||||
	int _views = 0;
 | 
			
		||||
	StoryViews _views;
 | 
			
		||||
	const TimeId _date = 0;
 | 
			
		||||
	const TimeId _expires = 0;
 | 
			
		||||
	TimeId _lastUpdateTime = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1254,12 +1254,17 @@ SiblingView Controller::sibling(SiblingType type) const {
 | 
			
		|||
	return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ViewsSlice Controller::views(PeerId offset) {
 | 
			
		||||
const Data::StoryViews &Controller::views(int limit, bool initial) {
 | 
			
		||||
	invalidate_weak_ptrs(&_viewsLoadGuard);
 | 
			
		||||
	if (!offset) {
 | 
			
		||||
	if (initial) {
 | 
			
		||||
		refreshViewsFromData();
 | 
			
		||||
	} else if (!sliceViewsTo(offset)) {
 | 
			
		||||
		return { .left = _viewsSlice.left };
 | 
			
		||||
	}
 | 
			
		||||
	if (_viewsSlice.total > _viewsSlice.list.size()
 | 
			
		||||
		&& _viewsSlice.list.size() < limit) {
 | 
			
		||||
		const auto done = viewsGotMoreCallback();
 | 
			
		||||
		const auto user = shownUser();
 | 
			
		||||
		auto &stories = user->owner().stories();
 | 
			
		||||
		stories.loadViewsSlice(_shown.story, _viewsSlice.nextOffset, done);
 | 
			
		||||
	}
 | 
			
		||||
	return _viewsSlice;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1268,27 +1273,25 @@ rpl::producer<> Controller::moreViewsLoaded() const {
 | 
			
		|||
	return _moreViewsLoaded.events();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Fn<void(std::vector<Data::StoryView>)> Controller::viewsGotMoreCallback() {
 | 
			
		||||
	return crl::guard(&_viewsLoadGuard, [=](
 | 
			
		||||
			const std::vector<Data::StoryView> &result) {
 | 
			
		||||
Fn<void(Data::StoryViews)> Controller::viewsGotMoreCallback() {
 | 
			
		||||
	return crl::guard(&_viewsLoadGuard, [=](Data::StoryViews result) {
 | 
			
		||||
		if (_viewsSlice.list.empty()) {
 | 
			
		||||
			const auto user = shownUser();
 | 
			
		||||
			auto &stories = user->owner().stories();
 | 
			
		||||
			if (const auto maybeStory = stories.lookup(_shown)) {
 | 
			
		||||
				_viewsSlice = {
 | 
			
		||||
					.list = result,
 | 
			
		||||
					.left = (*maybeStory)->views() - int(result.size()),
 | 
			
		||||
				};
 | 
			
		||||
				_viewsSlice = (*maybeStory)->viewsList();
 | 
			
		||||
			} else {
 | 
			
		||||
				_viewsSlice = {};
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			_viewsSlice.list.insert(
 | 
			
		||||
				end(_viewsSlice.list),
 | 
			
		||||
				begin(result),
 | 
			
		||||
				end(result));
 | 
			
		||||
			_viewsSlice.left
 | 
			
		||||
				= std::max(_viewsSlice.left - int(result.size()), 0);
 | 
			
		||||
				begin(result.list),
 | 
			
		||||
				end(result.list));
 | 
			
		||||
			_viewsSlice.total = result.nextOffset.isEmpty()
 | 
			
		||||
				? int(_viewsSlice.list.size())
 | 
			
		||||
				: std::max(result.total, int(_viewsSlice.list.size()));
 | 
			
		||||
			_viewsSlice.nextOffset = result.nextOffset;
 | 
			
		||||
		}
 | 
			
		||||
		_moreViewsLoaded.fire({});
 | 
			
		||||
	});
 | 
			
		||||
| 
						 | 
				
			
			@ -1439,46 +1442,9 @@ void Controller::refreshViewsFromData() {
 | 
			
		|||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	const auto story = *maybeStory;
 | 
			
		||||
	const auto &list = story->viewsList();
 | 
			
		||||
	const auto &views = story->viewsList();
 | 
			
		||||
	const auto total = story->views();
 | 
			
		||||
	_viewsSlice.list = list
 | 
			
		||||
		| ranges::views::take(Data::Stories::kViewsPerPage)
 | 
			
		||||
		| ranges::to_vector;
 | 
			
		||||
	_viewsSlice.left = total - int(_viewsSlice.list.size());
 | 
			
		||||
	if (_viewsSlice.list.empty() && _viewsSlice.left > 0) {
 | 
			
		||||
		const auto done = viewsGotMoreCallback();
 | 
			
		||||
		stories.loadViewsSlice(_shown.story, std::nullopt, done);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Controller::sliceViewsTo(PeerId offset) {
 | 
			
		||||
	Expects(shown());
 | 
			
		||||
 | 
			
		||||
	const auto user = shownUser();
 | 
			
		||||
	auto &stories = user->owner().stories();
 | 
			
		||||
	const auto maybeStory = stories.lookup(_shown);
 | 
			
		||||
	if (!maybeStory || !user->isSelf()) {
 | 
			
		||||
		_viewsSlice = {};
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	const auto story = *maybeStory;
 | 
			
		||||
	const auto &list = story->viewsList();
 | 
			
		||||
	const auto proj = [&](const Data::StoryView &single) {
 | 
			
		||||
		return single.peer->id;
 | 
			
		||||
	};
 | 
			
		||||
	const auto i = ranges::find(list, _viewsSlice.list.back());
 | 
			
		||||
	const auto add = (i != end(list)) ? int(end(list) - i - 1) : 0;
 | 
			
		||||
	const auto j = ranges::find(_viewsSlice.list, offset, proj);
 | 
			
		||||
	Assert(j != end(_viewsSlice.list));
 | 
			
		||||
	if (!add && (j + 1) == end(_viewsSlice.list)) {
 | 
			
		||||
		const auto done = viewsGotMoreCallback();
 | 
			
		||||
		stories.loadViewsSlice(_shown.story, _viewsSlice.list.back(), done);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	_viewsSlice.list.erase(begin(_viewsSlice.list), j + 1);
 | 
			
		||||
	_viewsSlice.list.insert(end(_viewsSlice.list), i + 1, end(list));
 | 
			
		||||
	_viewsSlice.left -= add;
 | 
			
		||||
	return true;
 | 
			
		||||
	_viewsSlice = story->viewsList();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Controller::unfocusReply() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,11 +104,6 @@ struct Layout {
 | 
			
		|||
	friend inline bool operator==(Layout, Layout) = default;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ViewsSlice {
 | 
			
		||||
	std::vector<Data::StoryView> list;
 | 
			
		||||
	int left = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Controller final : public base::has_weak_ptr {
 | 
			
		||||
public:
 | 
			
		||||
	explicit Controller(not_null<Delegate*> delegate);
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +153,7 @@ public:
 | 
			
		|||
	void repaintSibling(not_null<Sibling*> sibling);
 | 
			
		||||
	[[nodiscard]] SiblingView sibling(SiblingType type) const;
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] ViewsSlice views(PeerId offset);
 | 
			
		||||
	[[nodiscard]] const Data::StoryViews &views(int limit, bool initial);
 | 
			
		||||
	[[nodiscard]] rpl::producer<> moreViewsLoaded() const;
 | 
			
		||||
 | 
			
		||||
	void unfocusReply();
 | 
			
		||||
| 
						 | 
				
			
			@ -221,9 +216,8 @@ private:
 | 
			
		|||
	void moveFromShown();
 | 
			
		||||
 | 
			
		||||
	void refreshViewsFromData();
 | 
			
		||||
	bool sliceViewsTo(PeerId offset);
 | 
			
		||||
	[[nodiscard]] auto viewsGotMoreCallback()
 | 
			
		||||
		-> Fn<void(std::vector<Data::StoryView>)>;
 | 
			
		||||
		-> Fn<void(Data::StoryViews)>;
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] bool shown() const;
 | 
			
		||||
	[[nodiscard]] UserData *shownUser() const;
 | 
			
		||||
| 
						 | 
				
			
			@ -285,7 +279,7 @@ private:
 | 
			
		|||
	int _cachedSourceIndex = -1;
 | 
			
		||||
	bool _showingUnreadSources = false;
 | 
			
		||||
 | 
			
		||||
	ViewsSlice _viewsSlice;
 | 
			
		||||
	Data::StoryViews _viewsSlice;
 | 
			
		||||
	rpl::event_stream<> _moreViewsLoaded;
 | 
			
		||||
	base::has_weak_ptr _viewsLoadGuard;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -264,8 +264,8 @@ void RecentViews::showMenu() {
 | 
			
		|||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const auto views = _controller->views(PeerId());
 | 
			
		||||
	if (views.list.empty() && !views.left) {
 | 
			
		||||
	const auto views = _controller->views(kAddPerPage * 2, true);
 | 
			
		||||
	if (views.list.empty() && !views.total) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -276,7 +276,7 @@ void RecentViews::showMenu() {
 | 
			
		|||
		st::storiesViewsMenu);
 | 
			
		||||
	auto count = 0;
 | 
			
		||||
	const auto added = std::min(int(views.list.size()), kAddPerPage);
 | 
			
		||||
	const auto add = std::min(added + views.left, kAddPerPage);
 | 
			
		||||
	const auto add = std::min(views.total, kAddPerPage);
 | 
			
		||||
	const auto now = QDateTime::currentDateTime();
 | 
			
		||||
	for (const auto &entry  : views.list) {
 | 
			
		||||
		addMenuRow(entry, now);
 | 
			
		||||
| 
						 | 
				
			
			@ -393,23 +393,18 @@ void RecentViews::addMenuRowPlaceholder() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void RecentViews::rebuildMenuTail() {
 | 
			
		||||
	const auto offset = (_menuPlaceholderCount < _menuEntries.size())
 | 
			
		||||
		? (end(_menuEntries) - _menuPlaceholderCount - 1)->peer->id
 | 
			
		||||
		: PeerId();
 | 
			
		||||
	const auto views = _controller->views(offset);
 | 
			
		||||
	if (views.list.empty()) {
 | 
			
		||||
	const auto elements = _menuEntries.size() - _menuPlaceholderCount;
 | 
			
		||||
	const auto views = _controller->views(elements + kAddPerPage, false);
 | 
			
		||||
	if (views.list.size() <= elements) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	const auto now = QDateTime::currentDateTime();
 | 
			
		||||
	const auto added = std::min(
 | 
			
		||||
		_menuPlaceholderCount + kAddPerPage,
 | 
			
		||||
		int(views.list.size()));
 | 
			
		||||
	auto add = added;
 | 
			
		||||
	for (const auto &entry : views.list) {
 | 
			
		||||
		int(views.list.size() - elements));
 | 
			
		||||
	for (auto i = elements, till = i + added; i != till; ++i) {
 | 
			
		||||
		const auto &entry = views.list[i];
 | 
			
		||||
		addMenuRow(entry, now);
 | 
			
		||||
		if (!--add) {
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	_menuEntriesCount = _menuEntriesCount.current() + added;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -386,6 +386,7 @@ updateStory#205a4133 user_id:long story:StoryItem = Update;
 | 
			
		|||
updateReadStories#feb5345a user_id:long max_id:int = Update;
 | 
			
		||||
updateStoryID#1bf335b9 id:int random_id:long = Update;
 | 
			
		||||
updateStoriesStealthMode#2c084dc1 stealth_mode:StoriesStealthMode = Update;
 | 
			
		||||
updateSentStoryReaction#e3a73d20 user_id:long story_id:int reaction:Reaction = Update;
 | 
			
		||||
 | 
			
		||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1527,11 +1528,11 @@ messagePeerVoteMultiple#4628f6e6 peer:Peer options:Vector<bytes> date:int = Mess
 | 
			
		|||
 | 
			
		||||
sponsoredWebPage#3db8ec63 flags:# url:string site_name:string photo:flags.0?Photo = SponsoredWebPage;
 | 
			
		||||
 | 
			
		||||
storyViews#d36760cf flags:# views_count:int recent_viewers:flags.0?Vector<long> = StoryViews;
 | 
			
		||||
storyViews#c64c0b97 flags:# views_count:int reactions_count:int recent_viewers:flags.0?Vector<long> = StoryViews;
 | 
			
		||||
 | 
			
		||||
storyItemDeleted#51e6ee4f id:int = StoryItem;
 | 
			
		||||
storyItemSkipped#ffadc913 flags:# close_friends:flags.8?true id:int date:int expire_date:int = StoryItem;
 | 
			
		||||
storyItem#945953ba flags:# pinned:flags.5?true public:flags.7?true close_friends:flags.8?true min:flags.9?true noforwards:flags.10?true edited:flags.11?true contacts:flags.12?true selected_contacts:flags.13?true id:int date:int expire_date:int caption:flags.0?string entities:flags.1?Vector<MessageEntity> media:MessageMedia media_areas:flags.14?Vector<MediaArea> privacy:flags.2?Vector<PrivacyRule> views:flags.3?StoryViews = StoryItem;
 | 
			
		||||
storyItem#44c457ce flags:# pinned:flags.5?true public:flags.7?true close_friends:flags.8?true min:flags.9?true noforwards:flags.10?true edited:flags.11?true contacts:flags.12?true selected_contacts:flags.13?true id:int date:int expire_date:int caption:flags.0?string entities:flags.1?Vector<MessageEntity> media:MessageMedia media_areas:flags.14?Vector<MediaArea> privacy:flags.2?Vector<PrivacyRule> views:flags.3?StoryViews sent_reaction:flags.15?Reaction = StoryItem;
 | 
			
		||||
 | 
			
		||||
userStories#8611a200 flags:# user_id:long max_read_id:flags.0?int stories:Vector<StoryItem> = UserStories;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1542,9 +1543,9 @@ stories.stories#4fe57df1 count:int stories:Vector<StoryItem> users:Vector<User>
 | 
			
		|||
 | 
			
		||||
stories.userStories#37a6ff5f stories:UserStories users:Vector<User> = stories.UserStories;
 | 
			
		||||
 | 
			
		||||
storyView#d0b0a7de flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true user_id:long date:int = StoryView;
 | 
			
		||||
storyView#b0bdeac5 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true user_id:long date:int reaction:flags.2?Reaction = StoryView;
 | 
			
		||||
 | 
			
		||||
stories.storyViewsList#fb3f77ac count:int views:Vector<StoryView> users:Vector<User> = stories.StoryViewsList;
 | 
			
		||||
stories.storyViewsList#46e9b9ec flags:# count:int reactions_count:int views:Vector<StoryView> users:Vector<User> next_offset:flags.0?string = stories.StoryViewsList;
 | 
			
		||||
 | 
			
		||||
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2111,8 +2112,9 @@ stories.toggleAllStoriesHidden#7c2557c4 hidden:Bool = Bool;
 | 
			
		|||
stories.getAllReadUserStories#729c562c = Updates;
 | 
			
		||||
stories.readStories#edc5105b user_id:InputUser max_id:int = Vector<int>;
 | 
			
		||||
stories.incrementStoryViews#22126127 user_id:InputUser id:Vector<int> = Bool;
 | 
			
		||||
stories.getStoryViewsList#4b3b5e97 id:int offset_date:int offset_id:long limit:int = stories.StoryViewsList;
 | 
			
		||||
stories.getStoryViewsList#f95f61a4 flags:# just_contacts:flags.0?true q:flags.1?string id:int offset:string limit:int = stories.StoryViewsList;
 | 
			
		||||
stories.getStoriesViews#9a75d6a6 id:Vector<int> = stories.StoryViews;
 | 
			
		||||
stories.exportStoryLink#16e443ce user_id:InputUser id:int = ExportedStoryLink;
 | 
			
		||||
stories.report#c95be06a user_id:InputUser id:Vector<int> reason:ReportReason message:string = Bool;
 | 
			
		||||
stories.activateStealthMode#11d7ddae flags:# past:flags.0?true future:flags.1?true = Bool;
 | 
			
		||||
stories.activateStealthMode#57bbd166 flags:# past:flags.0?true future:flags.1?true = Updates;
 | 
			
		||||
stories.sendReaction#49aaa9b3 flags:# add_to_recent:flags.0?true user_id:InputUser story_id:int reaction:Reaction = Updates;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue