mirror of https://github.com/procxx/kepka.git
				
				
				
			Optimize getPeerDialog requests.
This commit is contained in:
		
							parent
							
								
									2a5bcd3eec
								
							
						
					
					
						commit
						287b3509ab
					
				| 
						 | 
				
			
			@ -257,26 +257,23 @@ void ApiWrap::getProxyPromotionDelayed(TimeId now, TimeId next) {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
void ApiWrap::proxyPromotionDone(const MTPhelp_ProxyData &proxy) {
 | 
			
		||||
	if (proxy.type() == mtpc_help_proxyDataEmpty) {
 | 
			
		||||
		const auto &data = proxy.c_help_proxyDataEmpty();
 | 
			
		||||
		const auto next = _proxyPromotionNextRequestTime = data.vexpires.v;
 | 
			
		||||
		getProxyPromotionDelayed(unixtime(), next);
 | 
			
		||||
		_session->data().setProxyPromoted(nullptr);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	Assert(proxy.type() == mtpc_help_proxyDataPromo);
 | 
			
		||||
	const auto &data = proxy.c_help_proxyDataPromo();
 | 
			
		||||
	const auto next = _proxyPromotionNextRequestTime = data.vexpires.v;
 | 
			
		||||
	getProxyPromotionDelayed(unixtime(), next);
 | 
			
		||||
	_proxyPromotionNextRequestTime = proxy.match([&](const auto &data) {
 | 
			
		||||
		return data.vexpires.v;
 | 
			
		||||
	});
 | 
			
		||||
	getProxyPromotionDelayed(unixtime(), _proxyPromotionNextRequestTime);
 | 
			
		||||
 | 
			
		||||
	proxy.match([&](const MTPDhelp_proxyDataEmpty &data) {
 | 
			
		||||
		_session->data().setProxyPromoted(nullptr);
 | 
			
		||||
	}, [&](const MTPDhelp_proxyDataPromo &data) {
 | 
			
		||||
		App::feedChats(data.vchats);
 | 
			
		||||
		App::feedUsers(data.vusers);
 | 
			
		||||
		const auto peerId = peerFromMTP(data.vpeer);
 | 
			
		||||
	const auto peer = App::peer(peerId);
 | 
			
		||||
		const auto peer = _session->data().peer(peerId);
 | 
			
		||||
		_session->data().setProxyPromoted(peer);
 | 
			
		||||
		if (const auto history = App::historyLoaded(peer)) {
 | 
			
		||||
			requestDialogEntry(history);
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApiWrap::requestDeepLinkInfo(
 | 
			
		||||
| 
						 | 
				
			
			@ -687,70 +684,79 @@ void ApiWrap::requestDialogEntry(not_null<Data::Feed*> feed) {
 | 
			
		|||
void ApiWrap::requestDialogEntry(
 | 
			
		||||
		not_null<History*> history,
 | 
			
		||||
		Fn<void()> callback) {
 | 
			
		||||
	const auto[i, ok] = _dialogRequests.try_emplace(history);
 | 
			
		||||
	const auto i = _dialogRequests.find(history);
 | 
			
		||||
	if (i != end(_dialogRequests)) {
 | 
			
		||||
		if (callback) {
 | 
			
		||||
			i->second.push_back(std::move(callback));
 | 
			
		||||
		}
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const auto [j, ok] = _dialogRequestsPending.try_emplace(history);
 | 
			
		||||
	if (callback) {
 | 
			
		||||
		j->second.push_back(std::move(callback));
 | 
			
		||||
	}
 | 
			
		||||
	if (!ok) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	const auto finalize = [=] {
 | 
			
		||||
		if (const auto callbacks = _dialogRequests.take(history)) {
 | 
			
		||||
			for (const auto &callback : *callbacks) {
 | 
			
		||||
				callback();
 | 
			
		||||
	if (_dialogRequestsPending.size() > 1) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	Core::App().postponeCall(crl::guard(_session, [=] {
 | 
			
		||||
		sendDialogRequests();
 | 
			
		||||
	}));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApiWrap::sendDialogRequests() {
 | 
			
		||||
	if (_dialogRequestsPending.empty()) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	auto histories = std::vector<not_null<History*>>();
 | 
			
		||||
	ranges::transform(
 | 
			
		||||
		_dialogRequestsPending,
 | 
			
		||||
		ranges::back_inserter(histories),
 | 
			
		||||
		[](const auto &pair) { return pair.first; });
 | 
			
		||||
	auto peers = QVector<MTPInputDialogPeer>();
 | 
			
		||||
	const auto dialogPeer = [](not_null<History*> history) {
 | 
			
		||||
		return MTP_inputDialogPeer(history->peer->input);
 | 
			
		||||
	};
 | 
			
		||||
	ranges::transform(
 | 
			
		||||
		histories,
 | 
			
		||||
		ranges::back_inserter(peers),
 | 
			
		||||
		dialogPeer);
 | 
			
		||||
	for (auto &[history, callbacks] : base::take(_dialogRequestsPending)) {
 | 
			
		||||
		_dialogRequests.emplace(history, std::move(callbacks));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const auto finalize = [=] {
 | 
			
		||||
		for (const auto history : histories) {
 | 
			
		||||
			dialogEntryApplied(history);
 | 
			
		||||
			history->updateChatListExistence();
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
	auto peers = QVector<MTPInputDialogPeer>(
 | 
			
		||||
		1,
 | 
			
		||||
		MTP_inputDialogPeer(history->peer->input));
 | 
			
		||||
	request(MTPmessages_GetPeerDialogs(
 | 
			
		||||
		MTP_vector(std::move(peers))
 | 
			
		||||
	)).done([=](const MTPmessages_PeerDialogs &result) {
 | 
			
		||||
		applyPeerDialogs(result);
 | 
			
		||||
		history->dialogEntryApplied();
 | 
			
		||||
		finalize();
 | 
			
		||||
	}).fail([=](const RPCError &error) {
 | 
			
		||||
		finalize();
 | 
			
		||||
	}).send();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApiWrap::requestDialogEntries(
 | 
			
		||||
		std::vector<not_null<History*>> histories) {
 | 
			
		||||
	const auto already = [&](not_null<History*> history) {
 | 
			
		||||
		const auto [i, ok] = _dialogRequests.try_emplace(history);
 | 
			
		||||
		return !ok;
 | 
			
		||||
	};
 | 
			
		||||
	histories.erase(ranges::remove_if(histories, already), end(histories));
 | 
			
		||||
	if (histories.empty()) {
 | 
			
		||||
		return;
 | 
			
		||||
void ApiWrap::dialogEntryApplied(not_null<History*> history) {
 | 
			
		||||
	history->dialogEntryApplied();
 | 
			
		||||
	if (const auto callbacks = _dialogRequestsPending.take(history)) {
 | 
			
		||||
		for (const auto &callback : *callbacks) {
 | 
			
		||||
			callback();
 | 
			
		||||
		}
 | 
			
		||||
	auto peers = QVector<MTPInputDialogPeer>();
 | 
			
		||||
	peers.reserve(histories.size());
 | 
			
		||||
	for (const auto history : histories) {
 | 
			
		||||
		peers.push_back(MTP_inputDialogPeer(history->peer->input));
 | 
			
		||||
	}
 | 
			
		||||
	const auto finalize = [=](std::vector<not_null<History*>> histories) {
 | 
			
		||||
		for (const auto history : histories) {
 | 
			
		||||
	if (const auto callbacks = _dialogRequests.take(history)) {
 | 
			
		||||
		for (const auto &callback : *callbacks) {
 | 
			
		||||
			callback();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
	};
 | 
			
		||||
	request(MTPmessages_GetPeerDialogs(
 | 
			
		||||
		MTP_vector(std::move(peers))
 | 
			
		||||
	)).done([=](const MTPmessages_PeerDialogs &result) {
 | 
			
		||||
		applyPeerDialogs(result);
 | 
			
		||||
		for (const auto history : histories) {
 | 
			
		||||
			history->dialogEntryApplied();
 | 
			
		||||
		}
 | 
			
		||||
		finalize(histories);
 | 
			
		||||
	}).fail([=](const RPCError &error) {
 | 
			
		||||
		finalize(histories);
 | 
			
		||||
	}).send();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApiWrap::applyPeerDialogs(const MTPmessages_PeerDialogs &dialogs) {
 | 
			
		||||
	Expects(dialogs.type() == mtpc_messages_peerDialogs);
 | 
			
		||||
| 
						 | 
				
			
			@ -1490,7 +1496,7 @@ void ApiWrap::applyLastParticipantsList(
 | 
			
		|||
	Notify::peerUpdatedDelayed(update);
 | 
			
		||||
 | 
			
		||||
	channel->mgInfo->botStatus = botStatus;
 | 
			
		||||
	if (App::main()) fullPeerUpdated().notify(channel);
 | 
			
		||||
	fullPeerUpdated().notify(channel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApiWrap::applyBotsList(
 | 
			
		||||
| 
						 | 
				
			
			@ -1532,7 +1538,7 @@ void ApiWrap::applyBotsList(
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	channel->mgInfo->botStatus = botStatus;
 | 
			
		||||
	if (App::main()) fullPeerUpdated().notify(channel);
 | 
			
		||||
	fullPeerUpdated().notify(channel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApiWrap::applyAdminsList(
 | 
			
		||||
| 
						 | 
				
			
			@ -1568,58 +1574,58 @@ void ApiWrap::applyAdminsList(
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApiWrap::requestSelfParticipant(ChannelData *channel) {
 | 
			
		||||
void ApiWrap::requestSelfParticipant(not_null<ChannelData*> channel) {
 | 
			
		||||
	if (_selfParticipantRequests.contains(channel)) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	auto requestId = request(MTPchannels_GetParticipant(
 | 
			
		||||
	const auto finalize = [=](UserId inviter, TimeId inviteDate) {
 | 
			
		||||
		channel->inviter = inviter;
 | 
			
		||||
		channel->inviteDate = inviteDate;
 | 
			
		||||
		if (const auto history = App::historyLoaded(channel)) {
 | 
			
		||||
			if (history->lastMessageKnown()) {
 | 
			
		||||
				history->checkJoinedMessage(true);
 | 
			
		||||
				history->owner().sendHistoryChangeNotifications();
 | 
			
		||||
			} else {
 | 
			
		||||
				requestDialogEntry(history);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
	_selfParticipantRequests.emplace(channel);
 | 
			
		||||
	request(MTPchannels_GetParticipant(
 | 
			
		||||
		channel->inputChannel,
 | 
			
		||||
		MTP_inputUserSelf()
 | 
			
		||||
	)).done([this, channel](const MTPchannels_ChannelParticipant &result) {
 | 
			
		||||
		_selfParticipantRequests.remove(channel);
 | 
			
		||||
		if (result.type() != mtpc_channels_channelParticipant) {
 | 
			
		||||
			LOG(("API Error: unknown type in gotSelfParticipant (%1)").arg(result.type()));
 | 
			
		||||
			channel->inviter = -1;
 | 
			
		||||
			if (App::main()) App::main()->onSelfParticipantUpdated(channel);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	)).done([=](const MTPchannels_ChannelParticipant &result) {
 | 
			
		||||
		_selfParticipantRequests.erase(channel);
 | 
			
		||||
		result.match([&](const MTPDchannels_channelParticipant &data) {
 | 
			
		||||
			App::feedUsers(data.vusers);
 | 
			
		||||
 | 
			
		||||
		auto &p = result.c_channels_channelParticipant();
 | 
			
		||||
		App::feedUsers(p.vusers);
 | 
			
		||||
 | 
			
		||||
		switch (p.vparticipant.type()) {
 | 
			
		||||
		case mtpc_channelParticipantSelf: {
 | 
			
		||||
			auto &d = p.vparticipant.c_channelParticipantSelf();
 | 
			
		||||
			channel->inviter = d.vinviter_id.v;
 | 
			
		||||
			channel->inviteDate = d.vdate.v;
 | 
			
		||||
		} break;
 | 
			
		||||
		case mtpc_channelParticipantCreator: {
 | 
			
		||||
			auto &d = p.vparticipant.c_channelParticipantCreator();
 | 
			
		||||
			channel->inviter = _session->userId();
 | 
			
		||||
			channel->inviteDate = channel->date;
 | 
			
		||||
			const auto &participant = data.vparticipant;
 | 
			
		||||
			participant.match([&](const MTPDchannelParticipantSelf &data) {
 | 
			
		||||
				finalize(data.vinviter_id.v, data.vdate.v);
 | 
			
		||||
			}, [&](const MTPDchannelParticipantCreator &) {
 | 
			
		||||
				if (channel->mgInfo) {
 | 
			
		||||
					channel->mgInfo->creator = _session->user();
 | 
			
		||||
				}
 | 
			
		||||
		} break;
 | 
			
		||||
		case mtpc_channelParticipantAdmin: {
 | 
			
		||||
			auto &d = p.vparticipant.c_channelParticipantAdmin();
 | 
			
		||||
			channel->inviter = (d.is_self() && d.has_inviter_id())
 | 
			
		||||
				? d.vinviter_id.v
 | 
			
		||||
				: 0;
 | 
			
		||||
			channel->inviteDate = d.vdate.v;
 | 
			
		||||
		} break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (App::main()) App::main()->onSelfParticipantUpdated(channel);
 | 
			
		||||
	}).fail([this, channel](const RPCError &error) {
 | 
			
		||||
		_selfParticipantRequests.remove(channel);
 | 
			
		||||
		if (error.type() == qstr("USER_NOT_PARTICIPANT")) {
 | 
			
		||||
			channel->inviter = -1;
 | 
			
		||||
		}
 | 
			
		||||
				finalize(_session->userId(), channel->date);
 | 
			
		||||
			}, [&](const MTPDchannelParticipantAdmin &data) {
 | 
			
		||||
				const auto inviter = (data.is_self()
 | 
			
		||||
					&& data.has_inviter_id())
 | 
			
		||||
					? data.vinviter_id.v
 | 
			
		||||
					: -1;
 | 
			
		||||
				finalize(inviter, data.vdate.v);
 | 
			
		||||
			}, [&](const MTPDchannelParticipantBanned &data) {
 | 
			
		||||
				LOG(("API Error: Got self banned participant."));
 | 
			
		||||
				finalize(-1, 0);
 | 
			
		||||
			}, [&](const MTPDchannelParticipant &data) {
 | 
			
		||||
				LOG(("API Error: Got self regular participant."));
 | 
			
		||||
				finalize(-1, 0);
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	}).fail([=](const RPCError &error) {
 | 
			
		||||
		_selfParticipantRequests.erase(channel);
 | 
			
		||||
		finalize(-1, 0);
 | 
			
		||||
	}).afterDelay(kSmallDelayMs).send();
 | 
			
		||||
 | 
			
		||||
	_selfParticipantRequests.insert(channel, requestId);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApiWrap::kickParticipant(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,7 +83,7 @@ public:
 | 
			
		|||
	void requestDialogEntry(
 | 
			
		||||
		not_null<History*> history,
 | 
			
		||||
		Fn<void()> callback = nullptr);
 | 
			
		||||
	void requestDialogEntries(std::vector<not_null<History*>> histories);
 | 
			
		||||
	void dialogEntryApplied(not_null<History*> history);
 | 
			
		||||
	//void applyFeedSources(const MTPDchannels_feedSources &data); // #feed
 | 
			
		||||
	//void setFeedChannels(
 | 
			
		||||
	//	not_null<Data::Feed*> feed,
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +146,7 @@ public:
 | 
			
		|||
	void markMediaRead(const base::flat_set<not_null<HistoryItem*>> &items);
 | 
			
		||||
	void markMediaRead(not_null<HistoryItem*> item);
 | 
			
		||||
 | 
			
		||||
	void requestSelfParticipant(ChannelData *channel);
 | 
			
		||||
	void requestSelfParticipant(not_null<ChannelData*> channel);
 | 
			
		||||
	void kickParticipant(not_null<ChatData*> chat, not_null<UserData*> user);
 | 
			
		||||
	void kickParticipant(
 | 
			
		||||
		not_null<ChannelData*> channel,
 | 
			
		||||
| 
						 | 
				
			
			@ -592,6 +592,8 @@ private:
 | 
			
		|||
		not_null<ChannelData*> channel);
 | 
			
		||||
	void migrateFail(not_null<PeerData*> peer, const RPCError &error);
 | 
			
		||||
 | 
			
		||||
	void sendDialogRequests();
 | 
			
		||||
 | 
			
		||||
	not_null<AuthSession*> _session;
 | 
			
		||||
 | 
			
		||||
	MessageDataRequests _messageDataRequests;
 | 
			
		||||
| 
						 | 
				
			
			@ -624,7 +626,7 @@ private:
 | 
			
		|||
		not_null<PeerData*>,
 | 
			
		||||
		mtpRequestId> _defaultRestrictionsRequests;
 | 
			
		||||
 | 
			
		||||
	QMap<ChannelData*, mtpRequestId> _selfParticipantRequests;
 | 
			
		||||
	base::flat_set<not_null<ChannelData*>> _selfParticipantRequests;
 | 
			
		||||
 | 
			
		||||
	base::flat_map<
 | 
			
		||||
		not_null<ChannelData*>,
 | 
			
		||||
| 
						 | 
				
			
			@ -666,6 +668,9 @@ private:
 | 
			
		|||
	base::flat_map<
 | 
			
		||||
		not_null<History*>,
 | 
			
		||||
		std::vector<Fn<void()>>> _dialogRequests;
 | 
			
		||||
	base::flat_map<
 | 
			
		||||
		not_null<History*>,
 | 
			
		||||
		std::vector<Fn<void()>>> _dialogRequestsPending;
 | 
			
		||||
	base::flat_set<not_null<History*>> _fakeChatListRequests;
 | 
			
		||||
 | 
			
		||||
	base::flat_map<not_null<History*>, mtpRequestId> _unreadMentionsRequests;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1298,14 +1298,14 @@ void DialogsInner::createDialog(Dialogs::Key key) {
 | 
			
		|||
 | 
			
		||||
	const auto from = dialogsOffset() + changed.movedFrom * st::dialogsRowHeight;
 | 
			
		||||
	const auto to = dialogsOffset() + changed.movedTo * st::dialogsRowHeight;
 | 
			
		||||
	if (!_dragging) {
 | 
			
		||||
	if (!_dragging && from != to) {
 | 
			
		||||
		// Don't jump in chats list scroll position while dragging.
 | 
			
		||||
		emit dialogMoved(from, to);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (creating) {
 | 
			
		||||
		refresh();
 | 
			
		||||
	} else if (_state == State::Default && changed.movedFrom != changed.movedTo) {
 | 
			
		||||
	} else if (_state == State::Default && from != to) {
 | 
			
		||||
		update(0, qMin(from, to), getFullWidth(), qAbs(from - to) + st::dialogsRowHeight);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1948,7 +1948,6 @@ bool DialogsInner::searchReceived(
 | 
			
		|||
	auto isGlobalSearch = (type == DialogsSearchFromStart || type == DialogsSearchFromOffset);
 | 
			
		||||
	auto isMigratedSearch = (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset);
 | 
			
		||||
 | 
			
		||||
	auto unknownUnreadCounts = std::vector<not_null<History*>>();
 | 
			
		||||
	TimeId lastDateFound = 0;
 | 
			
		||||
	for (const auto &message : messages) {
 | 
			
		||||
		auto msgId = IdFromMessage(message);
 | 
			
		||||
| 
						 | 
				
			
			@ -1966,7 +1965,7 @@ bool DialogsInner::searchReceived(
 | 
			
		|||
							_searchInChat,
 | 
			
		||||
							item));
 | 
			
		||||
					if (uniquePeers && !history->unreadCountKnown()) {
 | 
			
		||||
						unknownUnreadCounts.push_back(history);
 | 
			
		||||
						history->session().api().requestDialogEntry(history);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				lastDateFound = lastDate;
 | 
			
		||||
| 
						 | 
				
			
			@ -2001,9 +2000,6 @@ bool DialogsInner::searchReceived(
 | 
			
		|||
 | 
			
		||||
	refresh();
 | 
			
		||||
 | 
			
		||||
	if (!unknownUnreadCounts.empty()) {
 | 
			
		||||
		Auth().api().requestDialogEntries(std::move(unknownUnreadCounts));
 | 
			
		||||
	}
 | 
			
		||||
	return lastDateFound != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2123,16 +2119,15 @@ void DialogsInner::notify_historyMuteUpdated(History *history) {
 | 
			
		|||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		int from = dialogsOffset() + changed.movedFrom * st::dialogsRowHeight;
 | 
			
		||||
		int to = dialogsOffset() + changed.movedTo * st::dialogsRowHeight;
 | 
			
		||||
		if (!_dragging) {
 | 
			
		||||
		const auto from = dialogsOffset() + changed.movedFrom * st::dialogsRowHeight;
 | 
			
		||||
		const auto to = dialogsOffset() + changed.movedTo * st::dialogsRowHeight;
 | 
			
		||||
		if (!_dragging && from != to) {
 | 
			
		||||
			// Don't jump in chats list scroll position while dragging.
 | 
			
		||||
			emit dialogMoved(from, to);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (creating) {
 | 
			
		||||
			refresh();
 | 
			
		||||
		} else if (_state == State::Default && changed.movedFrom != changed.movedTo) {
 | 
			
		||||
		} else if (_state == State::Default && from != to) {
 | 
			
		||||
			update(0, qMin(from, to), getFullWidth(), qAbs(from - to) + st::dialogsRowHeight);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -481,21 +481,21 @@ void DialogsWidget::updateDialogsOffset(
 | 
			
		|||
	auto lastDate = TimeId(0);
 | 
			
		||||
	auto lastPeer = PeerId(0);
 | 
			
		||||
	auto lastMsgId = MsgId(0);
 | 
			
		||||
	const auto fillFromDialog = [&](const auto &dialog) {
 | 
			
		||||
	for (const auto &dialog : ranges::view::reverse(dialogs)) {
 | 
			
		||||
		dialog.match([&](const auto &dialog) {
 | 
			
		||||
			const auto peer = peerFromMTP(dialog.vpeer);
 | 
			
		||||
		const auto msgId = dialog.vtop_message.v;
 | 
			
		||||
		if (!peer || !msgId) {
 | 
			
		||||
			const auto messageId = dialog.vtop_message.v;
 | 
			
		||||
			if (!peer || !messageId) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			if (!lastPeer) {
 | 
			
		||||
				lastPeer = peer;
 | 
			
		||||
			}
 | 
			
		||||
			if (!lastMsgId) {
 | 
			
		||||
			lastMsgId = msgId;
 | 
			
		||||
				lastMsgId = messageId;
 | 
			
		||||
			}
 | 
			
		||||
		for (auto j = messages.size(); j != 0;) {
 | 
			
		||||
			const auto &message = messages[--j];
 | 
			
		||||
			if (IdFromMessage(message) == msgId
 | 
			
		||||
			for (const auto &message : ranges::view::reverse(messages)) {
 | 
			
		||||
				if (IdFromMessage(message) == messageId
 | 
			
		||||
					&& PeerFromMessage(message) == peer) {
 | 
			
		||||
					if (const auto date = DateFromMessage(message)) {
 | 
			
		||||
						lastDate = date;
 | 
			
		||||
| 
						 | 
				
			
			@ -503,14 +503,7 @@ void DialogsWidget::updateDialogsOffset(
 | 
			
		|||
					return;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
	};
 | 
			
		||||
	for (auto i = dialogs.size(); i != 0;) {
 | 
			
		||||
		const auto &dialog = dialogs[--i];
 | 
			
		||||
		switch (dialog.type()) {
 | 
			
		||||
		case mtpc_dialog: fillFromDialog(dialog.c_dialog()); break;
 | 
			
		||||
//		case mtpc_dialogFeed: fillFromDialog(dialog.c_dialogFeed()); break; // #feed
 | 
			
		||||
		default: Unexpected("Type in DialogsWidget::updateDialogsOffset");
 | 
			
		||||
		}
 | 
			
		||||
		});
 | 
			
		||||
		if (lastDate) {
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
#include "lang/lang_keys.h"
 | 
			
		||||
#include "apiwrap.h"
 | 
			
		||||
#include "mainwidget.h"
 | 
			
		||||
#include "application.h"
 | 
			
		||||
#include "mainwindow.h"
 | 
			
		||||
#include "storage/localstorage.h"
 | 
			
		||||
#include "observer_peer.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -2178,7 +2179,9 @@ void History::setChatListMessageFromLast() {
 | 
			
		|||
 | 
			
		||||
void History::requestChatListMessage() {
 | 
			
		||||
	if (!lastMessageKnown()) {
 | 
			
		||||
		session().api().requestDialogEntry(this);
 | 
			
		||||
		session().api().requestDialogEntry(this, [=] {
 | 
			
		||||
			requestChatListMessage();
 | 
			
		||||
		});
 | 
			
		||||
		return;
 | 
			
		||||
	} else if (chatListMessageKnown()) {
 | 
			
		||||
		return;
 | 
			
		||||
| 
						 | 
				
			
			@ -2336,13 +2339,16 @@ void History::applyDialog(const MTPDdialog &data) {
 | 
			
		|||
	if (data.has_draft() && data.vdraft.type() == mtpc_draftMessage) {
 | 
			
		||||
		Data::applyPeerCloudDraft(peer->id, data.vdraft.c_draftMessage());
 | 
			
		||||
	}
 | 
			
		||||
	session().api().dialogEntryApplied(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void History::dialogEntryApplied() {
 | 
			
		||||
	if (!lastMessageKnown()) {
 | 
			
		||||
		setLastMessage(nullptr);
 | 
			
		||||
	}
 | 
			
		||||
	if (!chatListMessageKnown()) {
 | 
			
		||||
	if (peer->migrateTo()) {
 | 
			
		||||
		return;
 | 
			
		||||
	} else if (!chatListMessageKnown()) {
 | 
			
		||||
		requestChatListMessage();
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -2371,7 +2377,7 @@ void History::dialogEntryApplied() {
 | 
			
		|||
	if (chatListTimeId() != 0 && loadedAtBottom()) {
 | 
			
		||||
		if (const auto channel = peer->asChannel()) {
 | 
			
		||||
			const auto inviter = channel->inviter;
 | 
			
		||||
			if (inviter != 0
 | 
			
		||||
			if (inviter > 0
 | 
			
		||||
				&& chatListTimeId() <= channel->inviteDate
 | 
			
		||||
				&& channel->amIn()) {
 | 
			
		||||
				if (const auto from = App::userLoaded(inviter)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2380,7 +2386,6 @@ void History::dialogEntryApplied() {
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	updateChatListExistence();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool History::clearUnreadOnClientSide() const {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -306,7 +306,7 @@ void NotificationsController::applyFeedDialogs(
 | 
			
		|||
					const auto history = App::history(peerId);
 | 
			
		||||
					const auto channel = history->peer->asChannel();
 | 
			
		||||
					history->applyDialog(dialog.c_dialog());
 | 
			
		||||
					channels.push_back(channel);
 | 
			
		||||
					channels.emplace_back(channel);
 | 
			
		||||
				} else {
 | 
			
		||||
					LOG(("API Error: "
 | 
			
		||||
						"Unexpected non-channel in feed dialogs list."));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3305,24 +3305,6 @@ void MainWidget::openPeerByName(
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWidget::onSelfParticipantUpdated(ChannelData *channel) {
 | 
			
		||||
	auto history = App::historyLoaded(channel->id);
 | 
			
		||||
	if (_updatedChannels.contains(channel)) {
 | 
			
		||||
		_updatedChannels.remove(channel);
 | 
			
		||||
		if (!history) {
 | 
			
		||||
			history = App::history(channel);
 | 
			
		||||
		}
 | 
			
		||||
		if (history->isEmpty()) {
 | 
			
		||||
			Auth().api().requestDialogEntry(history);
 | 
			
		||||
		} else {
 | 
			
		||||
			history->checkJoinedMessage(true);
 | 
			
		||||
		}
 | 
			
		||||
	} else if (history) {
 | 
			
		||||
		history->checkJoinedMessage();
 | 
			
		||||
	}
 | 
			
		||||
	Auth().data().sendHistoryChangeNotifications();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MainWidget::contentOverlapped(const QRect &globalRect) {
 | 
			
		||||
	return (_history->contentOverlapped(globalRect)
 | 
			
		||||
			|| _playerPanel->overlaps(globalRect)
 | 
			
		||||
| 
						 | 
				
			
			@ -4461,24 +4443,23 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
 | 
			
		|||
		auto &d = update.c_updateChannel();
 | 
			
		||||
		if (const auto channel = App::channelLoaded(d.vchannel_id.v)) {
 | 
			
		||||
			channel->inviter = UserId(0);
 | 
			
		||||
			if (channel->amIn()
 | 
			
		||||
				&& !channel->amCreator()
 | 
			
		||||
				&& App::history(channel->id)) {
 | 
			
		||||
				_updatedChannels.insert(channel, true);
 | 
			
		||||
				Auth().api().requestSelfParticipant(channel);
 | 
			
		||||
			}
 | 
			
		||||
			if (channel->amIn()) {
 | 
			
		||||
				const auto history = App::history(channel);
 | 
			
		||||
				if (const auto feed = channel->feed()) {
 | 
			
		||||
					feed->requestChatListMessage();
 | 
			
		||||
					if (!feed->unreadCountKnown()) {
 | 
			
		||||
						feed->session().api().requestDialogEntry(feed);
 | 
			
		||||
					}
 | 
			
		||||
			} else if (channel->amIn()) {
 | 
			
		||||
				const auto history = App::history(channel->id);
 | 
			
		||||
				} else {
 | 
			
		||||
					history->requestChatListMessage();
 | 
			
		||||
					if (!history->unreadCountKnown()) {
 | 
			
		||||
						history->session().api().requestDialogEntry(history);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (!channel->amCreator()) {
 | 
			
		||||
					Auth().api().requestSelfParticipant(channel);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} break;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -253,7 +253,6 @@ public:
 | 
			
		|||
 | 
			
		||||
	void scheduleViewIncrement(HistoryItem *item);
 | 
			
		||||
 | 
			
		||||
	void onSelfParticipantUpdated(ChannelData *channel);
 | 
			
		||||
	void feedChannelDifference(const MTPDupdates_channelDifference &data);
 | 
			
		||||
 | 
			
		||||
	// Mayde public for ApiWrap, while it is still here.
 | 
			
		||||
| 
						 | 
				
			
			@ -537,9 +536,6 @@ private:
 | 
			
		|||
	int _cachedY = 0;
 | 
			
		||||
	SingleTimer _cacheBackgroundTimer;
 | 
			
		||||
 | 
			
		||||
	typedef QMap<ChannelData*, bool> UpdatedChannels;
 | 
			
		||||
	UpdatedChannels _updatedChannels;
 | 
			
		||||
 | 
			
		||||
	PhotoData *_deletingPhoto = nullptr;
 | 
			
		||||
 | 
			
		||||
	typedef QMap<MsgId, bool> ViewsIncrementMap;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue