mirror of https://github.com/procxx/kepka.git
				
				
				
			participants handled good in supergroups: auto-load in profiles, outdate when something changes
This commit is contained in:
		
							parent
							
								
									583c0e5904
								
							
						
					
					
						commit
						84a47d3be7
					
				|  | @ -316,10 +316,11 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt | ||||||
| 		channel->about = qs(f.vabout); | 		channel->about = qs(f.vabout); | ||||||
| 		int32 newCount = f.has_participants_count() ? f.vparticipants_count.v : 0; | 		int32 newCount = f.has_participants_count() ? f.vparticipants_count.v : 0; | ||||||
| 		if (newCount != channel->count) { | 		if (newCount != channel->count) { | ||||||
| 			channel->count = newCount; |  | ||||||
| 			if (channel->isMegagroup() && !channel->mgInfo->lastParticipants.isEmpty()) { | 			if (channel->isMegagroup() && !channel->mgInfo->lastParticipants.isEmpty()) { | ||||||
| 				requestLastParticipants(channel); | 				channel->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated; | ||||||
|  | 				channel->mgInfo->lastParticipantsCount = channel->count; | ||||||
| 			} | 			} | ||||||
|  | 			channel->count = newCount; | ||||||
| 		} | 		} | ||||||
| 		channel->adminsCount = f.has_admins_count() ? f.vadmins_count.v : 0; | 		channel->adminsCount = f.has_admins_count() ? f.vadmins_count.v : 0; | ||||||
| 		channel->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString(); | 		channel->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString(); | ||||||
|  | @ -421,11 +422,24 @@ void ApiWrap::requestPeers(const QList<PeerData*> &peers) { | ||||||
| 	if (!users.isEmpty()) MTP::send(MTPusers_GetUsers(MTP_vector<MTPInputUser>(users)), rpcDone(&ApiWrap::gotUsers)); | 	if (!users.isEmpty()) MTP::send(MTPusers_GetUsers(MTP_vector<MTPInputUser>(users)), rpcDone(&ApiWrap::gotUsers)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ApiWrap::requestLastParticipants(ChannelData *peer) { | void ApiWrap::requestLastParticipants(ChannelData *peer, bool fromStart) { | ||||||
| 	if (!peer || !peer->isMegagroup() || _participantsRequests.contains(peer)) return; | 	if (!peer || !peer->isMegagroup()) return; | ||||||
| 	mtpRequestId req = MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsRecent(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer)); | 	if ((peer->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated) || peer->lastParticipantsCountOutdated()) { | ||||||
| 	_participantsRequests.insert(peer, req); | 		fromStart = true; | ||||||
| 	MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsBots(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer)); | 	} | ||||||
|  | 	QMap<PeerData*, mtpRequestId>::iterator i = _participantsRequests.find(peer); | ||||||
|  | 	if (i != _participantsRequests.cend()) { | ||||||
|  | 		if (fromStart && i.value() < 0) { // was not loading from start
 | ||||||
|  | 			_participantsRequests.erase(i); | ||||||
|  | 		} else { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	mtpRequestId req = MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsRecent(), MTP_int(fromStart ? 0 : peer->mgInfo->lastParticipants.size()), MTP_int(1)), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer)); | ||||||
|  | 	_participantsRequests.insert(peer, fromStart ? req : -req); | ||||||
|  | 	if (fromStart) { | ||||||
|  | 		_botsRequests.insert(peer, MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsBots(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer))); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) { | void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) { | ||||||
|  | @ -477,60 +491,80 @@ bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &error) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req) { | void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req) { | ||||||
| 	bool bots = (_participantsRequests.value(peer) != req); | 	bool bots = (_botsRequests.value(peer) == req), fromStart = false; | ||||||
| 
 | 	if (bots) { | ||||||
| 	if (!bots) { | 		_botsRequests.remove(peer); | ||||||
|  | 	} else { | ||||||
|  | 		int32 was = _participantsRequests.value(peer); | ||||||
|  | 		if (was == req) { | ||||||
|  | 			fromStart = true; | ||||||
|  | 		} else if (was != -req) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
| 		_participantsRequests.remove(peer); | 		_participantsRequests.remove(peer); | ||||||
| 	} | 	} | ||||||
| 	if (!peer->mgInfo) return; |  | ||||||
| 
 | 
 | ||||||
| 	if (result.type() == mtpc_channels_channelParticipants) { | 	if (!peer->mgInfo || result.type() != mtpc_channels_channelParticipants) return; | ||||||
| 		const MTPDchannels_channelParticipants &d(result.c_channels_channelParticipants()); | 
 | ||||||
| 		const QVector<MTPChannelParticipant> &v(d.vparticipants.c_vector().v); | 	if (bots) { | ||||||
| 		App::feedUsers(d.vusers); | 		peer->mgInfo->bots.clear(); | ||||||
| 		int32 botStatus = peer->mgInfo->botStatus; | 		peer->mgInfo->botStatus = -1; | ||||||
| 		if (bots) { | 	} else if (fromStart) { | ||||||
| 			peer->mgInfo->bots.clear(); | 		peer->mgInfo->lastAdmins.clear(); | ||||||
| 			botStatus = -1; | 		peer->mgInfo->lastParticipants.clear(); | ||||||
| 		} else { | 		peer->mgInfo->lastParticipantsStatus = MegagroupInfo::LastParticipantsUpToDate; | ||||||
| 			peer->mgInfo->lastParticipants.clear(); | 	} | ||||||
| 			peer->mgInfo->lastAdmins.clear(); | 
 | ||||||
|  | 	const MTPDchannels_channelParticipants &d(result.c_channels_channelParticipants()); | ||||||
|  | 	const QVector<MTPChannelParticipant> &v(d.vparticipants.c_vector().v); | ||||||
|  | 	App::feedUsers(d.vusers); | ||||||
|  | 	bool added = false; | ||||||
|  | 	int32 botStatus = peer->mgInfo->botStatus; | ||||||
|  | 	for (QVector<MTPChannelParticipant>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { | ||||||
|  | 		int32 userId = 0; | ||||||
|  | 		bool admin = false; | ||||||
|  | 
 | ||||||
|  | 		switch (i->type()) { | ||||||
|  | 		case mtpc_channelParticipant: userId = i->c_channelParticipant().vuser_id.v; break; | ||||||
|  | 		case mtpc_channelParticipantSelf: userId = i->c_channelParticipantSelf().vuser_id.v; break; | ||||||
|  | 		case mtpc_channelParticipantModerator: userId = i->c_channelParticipantModerator().vuser_id.v; break; | ||||||
|  | 		case mtpc_channelParticipantEditor: userId = i->c_channelParticipantEditor().vuser_id.v; admin = true; break; | ||||||
|  | 		case mtpc_channelParticipantKicked: userId = i->c_channelParticipantKicked().vuser_id.v; break; | ||||||
|  | 		case mtpc_channelParticipantCreator: userId = i->c_channelParticipantCreator().vuser_id.v; admin = true; break; | ||||||
| 		} | 		} | ||||||
| 		for (QVector<MTPChannelParticipant>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { | 		UserData *u = App::user(userId); | ||||||
| 			int32 userId = 0; | 		if (bots) { | ||||||
| 			bool admin = false; | 			if (u->botInfo) { | ||||||
| 
 | 				peer->mgInfo->bots.insert(u, true); | ||||||
| 			switch (i->type()) { | 				botStatus = (botStatus > 0/* || i.key()->botInfo->readsAllHistory*/) ? 2 : 1; | ||||||
| 			case mtpc_channelParticipant: userId = i->c_channelParticipant().vuser_id.v; break; |  | ||||||
| 			case mtpc_channelParticipantSelf: userId = i->c_channelParticipantSelf().vuser_id.v; break; |  | ||||||
| 			case mtpc_channelParticipantModerator: userId = i->c_channelParticipantModerator().vuser_id.v; break; |  | ||||||
| 			case mtpc_channelParticipantEditor: userId = i->c_channelParticipantEditor().vuser_id.v; admin = true; break; |  | ||||||
| 			case mtpc_channelParticipantKicked: userId = i->c_channelParticipantKicked().vuser_id.v; break; |  | ||||||
| 			case mtpc_channelParticipantCreator: userId = i->c_channelParticipantCreator().vuser_id.v; admin = true; break; |  | ||||||
| 			} | 			} | ||||||
| 			UserData *u = App::user(userId); | 		} else { | ||||||
| 			if (bots) { | 			if (peer->mgInfo->lastParticipants.indexOf(u) < 0) { | ||||||
| 				if (u->botInfo) { |  | ||||||
| 					peer->mgInfo->bots.insert(u, true); |  | ||||||
| 					botStatus = (botStatus > 0/* || i.key()->botInfo->readsAllHistory*/) ? 2 : 1; |  | ||||||
| 				} |  | ||||||
| 			} else { |  | ||||||
| 				peer->mgInfo->lastParticipants.push_back(u); | 				peer->mgInfo->lastParticipants.push_back(u); | ||||||
| 				if (admin) peer->mgInfo->lastAdmins.insert(u, true); | 				if (admin) peer->mgInfo->lastAdmins.insert(u, true); | ||||||
|  | 				added = true; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if (d.vcount.v > peer->count) { |  | ||||||
| 			peer->count = d.vcount.v; |  | ||||||
| 		} else if (v.count() > peer->count) { |  | ||||||
| 			peer->count = v.count(); |  | ||||||
| 		} |  | ||||||
| 		if (App::main()) emit fullPeerUpdated(peer); |  | ||||||
| 	} | 	} | ||||||
|  | 	if (d.vcount.v > peer->count) { | ||||||
|  | 		peer->count = d.vcount.v; | ||||||
|  | 	} else if (v.count() > peer->count) { | ||||||
|  | 		peer->count = v.count(); | ||||||
|  | 	} | ||||||
|  | 	if (!bots && v.isEmpty()) { | ||||||
|  | 		peer->count = peer->mgInfo->lastParticipants.size(); | ||||||
|  | 	} | ||||||
|  | 	peer->mgInfo->botStatus = botStatus; | ||||||
|  | 	if (App::main()) emit fullPeerUpdated(peer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool ApiWrap::lastParticipantsFail(ChannelData *peer, const RPCError &error) { | bool ApiWrap::lastParticipantsFail(ChannelData *peer, const RPCError &error, mtpRequestId req) { | ||||||
| 	if (mtpIsFlood(error)) return false; | 	if (mtpIsFlood(error)) return false; | ||||||
| 	_participantsRequests.remove(peer); | 	if (_participantsRequests.value(peer) == req || _participantsRequests.value(peer) == -req) { | ||||||
|  | 		_participantsRequests.remove(peer); | ||||||
|  | 	} else if (_botsRequests.value(peer) == req) { | ||||||
|  | 		_botsRequests.remove(peer); | ||||||
|  | 	} | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -603,10 +637,13 @@ void ApiWrap::kickParticipantDone(KickRequest kick, const MTPUpdates &result, mt | ||||||
| 		if (i >= 0) { | 		if (i >= 0) { | ||||||
| 			kick.first->asChannel()->mgInfo->lastParticipants.removeAt(i); | 			kick.first->asChannel()->mgInfo->lastParticipants.removeAt(i); | ||||||
| 			kick.first->asChannel()->mgInfo->lastAdmins.remove(kick.second); | 			kick.first->asChannel()->mgInfo->lastAdmins.remove(kick.second); | ||||||
| 			kick.first->asChannel()->mgInfo->bots.remove(kick.second); |  | ||||||
| 		} | 		} | ||||||
|  | 		kick.first->asChannel()->mgInfo->bots.remove(kick.second); | ||||||
| 		if (kick.first->asChannel()->count > 1) { | 		if (kick.first->asChannel()->count > 1) { | ||||||
| 			kick.first->asChannel()->count--; | 			kick.first->asChannel()->count--; | ||||||
|  | 		} else { | ||||||
|  | 			kick.first->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated; | ||||||
|  | 			kick.first->asChannel()->mgInfo->lastParticipantsCount = 0; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	emit fullPeerUpdated(kick.first); | 	emit fullPeerUpdated(kick.first); | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ public: | ||||||
| 	void requestFullPeer(PeerData *peer); | 	void requestFullPeer(PeerData *peer); | ||||||
| 	void requestPeer(PeerData *peer); | 	void requestPeer(PeerData *peer); | ||||||
| 	void requestPeers(const QList<PeerData*> &peers); | 	void requestPeers(const QList<PeerData*> &peers); | ||||||
| 	void requestLastParticipants(ChannelData *peer); | 	void requestLastParticipants(ChannelData *peer, bool fromStart = true); | ||||||
| 
 | 
 | ||||||
| 	void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result); | 	void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result); | ||||||
| 	void processFullPeer(PeerData *peer, const MTPUserFull &result); | 	void processFullPeer(PeerData *peer, const MTPUserFull &result); | ||||||
|  | @ -96,8 +96,8 @@ private: | ||||||
| 	PeerRequests _peerRequests; | 	PeerRequests _peerRequests; | ||||||
| 
 | 
 | ||||||
| 	void lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req); | 	void lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req); | ||||||
| 	bool lastParticipantsFail(ChannelData *peer, const RPCError &error); | 	bool lastParticipantsFail(ChannelData *peer, const RPCError &error, mtpRequestId req); | ||||||
| 	PeerRequests _participantsRequests; | 	PeerRequests _participantsRequests, _botsRequests; | ||||||
| 
 | 
 | ||||||
| 	typedef QPair<PeerData*, UserData*> KickRequest; | 	typedef QPair<PeerData*, UserData*> KickRequest; | ||||||
| 	typedef QMap<KickRequest, mtpRequestId> KickRequests; | 	typedef QMap<KickRequest, mtpRequestId> KickRequests; | ||||||
|  |  | ||||||
|  | @ -1791,8 +1791,9 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque | ||||||
| 				peer = peerFromMTP(d.c_dialog().vpeer); | 				peer = peerFromMTP(d.c_dialog().vpeer); | ||||||
| 			break; | 			break; | ||||||
| 			case mtpc_dialogChannel: | 			case mtpc_dialogChannel: | ||||||
| 				msgId = d.c_dialogChannel().vtop_important_message.v; | 				//msgId = d.c_dialogChannel().vtop_important_message.v;
 | ||||||
| 				if (!msgId) msgId = d.c_dialogChannel().vtop_message.v; | 				//if (!msgId) msgId = d.c_dialogChannel().vtop_message.v;
 | ||||||
|  | 				msgId = d.c_dialogChannel().vtop_message.v; | ||||||
| 				peer = peerFromMTP(d.c_dialogChannel().vpeer); | 				peer = peerFromMTP(d.c_dialogChannel().vpeer); | ||||||
| 			break; | 			break; | ||||||
| 			} | 			} | ||||||
|  | @ -1802,7 +1803,7 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque | ||||||
| 					if (!lastMsgId) lastMsgId = msgId; | 					if (!lastMsgId) lastMsgId = msgId; | ||||||
| 					for (int32 j = m->size(); j > 0;) { | 					for (int32 j = m->size(); j > 0;) { | ||||||
| 						const MTPMessage &d(m->at(--j)); | 						const MTPMessage &d(m->at(--j)); | ||||||
| 						if (idFromMessage(d) == msgId) { | 						if (idFromMessage(d) == msgId && peerFromMessage(d) == peer) { | ||||||
| 							int32 date = dateFromMessage(d); | 							int32 date = dateFromMessage(d); | ||||||
| 							if (date) lastDate = date; | 							if (date) lastDate = date; | ||||||
| 							break; | 							break; | ||||||
|  |  | ||||||
|  | @ -3006,7 +3006,7 @@ void MentionsDropdown::updateFiltered(bool toDown) { | ||||||
| 		} | 		} | ||||||
| 	} else if (_filter.at(0) == '@' && _channel && _channel->isMegagroup()) { | 	} else if (_filter.at(0) == '@' && _channel && _channel->isMegagroup()) { | ||||||
| 		QMultiMap<int32, UserData*> ordered; | 		QMultiMap<int32, UserData*> ordered; | ||||||
| 		if (_channel->mgInfo->lastParticipants.isEmpty()) { | 		if (_channel->mgInfo->lastParticipants.isEmpty() || _channel->lastParticipantsCountOutdated()) { | ||||||
| 			if (App::api()) App::api()->requestLastParticipants(_channel); | 			if (App::api()) App::api()->requestLastParticipants(_channel); | ||||||
| 		} else { | 		} else { | ||||||
| 			rows.reserve(_channel->mgInfo->lastParticipants.size()); | 			rows.reserve(_channel->mgInfo->lastParticipants.size()); | ||||||
|  |  | ||||||
|  | @ -1482,12 +1482,26 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo | ||||||
| 			switch (d.vaction.type()) { | 			switch (d.vaction.type()) { | ||||||
| 			case mtpc_messageActionChatAddUser: { | 			case mtpc_messageActionChatAddUser: { | ||||||
| 				const MTPDmessageActionChatAddUser &d(action.c_messageActionChatAddUser()); | 				const MTPDmessageActionChatAddUser &d(action.c_messageActionChatAddUser()); | ||||||
| 				// App::user(App::peerFromUser(d.vuser_id)); added
 | 				if (peer->isMegagroup()) { | ||||||
|  | 					peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated; | ||||||
|  | 					const QVector<MTPint> &v(d.vusers.c_vector().v); | ||||||
|  | 					for (int32 i = 0, l = v.size(); i < l; ++i) { | ||||||
|  | 						if (UserData *user = App::userLoaded(peerFromUser(v.at(i)))) { | ||||||
|  | 							if (peer->asChannel()->mgInfo->lastParticipants.indexOf(user) < 0) { | ||||||
|  | 								peer->asChannel()->mgInfo->lastParticipants.push_front(user); | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
| 			} break; | 			} break; | ||||||
| 
 | 
 | ||||||
| 			case mtpc_messageActionChatJoinedByLink: { | 			case mtpc_messageActionChatJoinedByLink: { | ||||||
| 				const MTPDmessageActionChatJoinedByLink &d(action.c_messageActionChatJoinedByLink()); | 				const MTPDmessageActionChatJoinedByLink &d(action.c_messageActionChatJoinedByLink()); | ||||||
| 				// App::user(App::peerFromUser(d.vuser_id)); added
 | 				if (peer->isMegagroup()) { | ||||||
|  | 					if (result->from()->isUser() && peer->asChannel()->mgInfo->lastParticipants.indexOf(result->from()->asUser()) < 0) { | ||||||
|  | 						peer->asChannel()->mgInfo->lastParticipants.push_front(result->from()->asUser()); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
| 			} break; | 			} break; | ||||||
| 
 | 
 | ||||||
| 			case mtpc_messageActionChatDeletePhoto: { | 			case mtpc_messageActionChatDeletePhoto: { | ||||||
|  | @ -1731,8 +1745,9 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a | ||||||
| 			QList<UserData*> *lastAuthors = 0; | 			QList<UserData*> *lastAuthors = 0; | ||||||
| 			if (peer->isChat()) { | 			if (peer->isChat()) { | ||||||
| 				lastAuthors = &peer->asChat()->lastAuthors; | 				lastAuthors = &peer->asChat()->lastAuthors; | ||||||
| 			} else if (peer->isMegagroup() && !peer->asChannel()->mgInfo->lastParticipants.isEmpty()) { | 			} else if (peer->isMegagroup()) { | ||||||
| 				lastAuthors = &peer->asChannel()->mgInfo->lastParticipants; | 				lastAuthors = &peer->asChannel()->mgInfo->lastParticipants; | ||||||
|  | 				peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated; | ||||||
| 			} | 			} | ||||||
| 			if (lastAuthors) { | 			if (lastAuthors) { | ||||||
| 				int prev = lastAuthors->indexOf(adding->from()->asUser()); | 				int prev = lastAuthors->indexOf(adding->from()->asUser()); | ||||||
|  | @ -1948,29 +1963,28 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM | ||||||
| 				lastAuthors = &peer->asChat()->lastAuthors; | 				lastAuthors = &peer->asChat()->lastAuthors; | ||||||
| 				markupSenders = &peer->asChat()->markupSenders; | 				markupSenders = &peer->asChat()->markupSenders; | ||||||
| 			} else if (peer->isMegagroup()) { | 			} else if (peer->isMegagroup()) { | ||||||
| 				if (!peer->asChannel()->mgInfo->lastParticipants.isEmpty()) { | 				lastAuthors = &peer->asChannel()->mgInfo->lastParticipants; | ||||||
| 					lastAuthors = &peer->asChannel()->mgInfo->lastParticipants; |  | ||||||
| 				} |  | ||||||
| 				markupSenders = &peer->asChannel()->mgInfo->markupSenders; | 				markupSenders = &peer->asChannel()->mgInfo->markupSenders; | ||||||
|  | 				peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated; | ||||||
| 			} | 			} | ||||||
| 			for (int32 i = block->items.size(); i > 0; --i) { | 			for (int32 i = block->items.size(); i > 0; --i) { | ||||||
| 				HistoryItem *item = block->items[i - 1]; | 				HistoryItem *item = block->items[i - 1]; | ||||||
| 				if (!item->indexInOverview()) continue; | 				if (item->indexInOverview()) { | ||||||
| 
 | 					HistoryMedia *media = item->getMedia(true); | ||||||
| 				HistoryMedia *media = item->getMedia(true); | 					if (media) { | ||||||
| 				if (media) { | 						HistoryMediaType mt = media->type(); | ||||||
| 					HistoryMediaType mt = media->type(); | 						MediaOverviewType t = mediaToOverviewType(mt); | ||||||
| 					MediaOverviewType t = mediaToOverviewType(mt); | 						if (t != OverviewCount) { | ||||||
| 					if (t != OverviewCount) { | 							if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->document()->song()) { | ||||||
| 						if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->document()->song()) { | 								if (addToOverviewFront(item, OverviewAudioDocuments)) mask |= (1 << OverviewAudioDocuments); | ||||||
| 							if (addToOverviewFront(item, OverviewAudioDocuments)) mask |= (1 << OverviewAudioDocuments); | 							} else { | ||||||
| 						} else { | 								if (addToOverviewFront(item, t)) mask |= (1 << t); | ||||||
| 							if (addToOverviewFront(item, t)) mask |= (1 << t); | 							} | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 					if (item->hasTextLinks()) { | ||||||
| 				if (item->hasTextLinks()) { | 						if (addToOverviewFront(item, OverviewLinks)) mask |= (1 << OverviewLinks); | ||||||
| 					if (addToOverviewFront(item, OverviewLinks)) mask |= (1 << OverviewLinks); | 					} | ||||||
| 				} | 				} | ||||||
| 				if (item->from()->id) { | 				if (item->from()->id) { | ||||||
| 					if (lastAuthors) { // chats
 | 					if (lastAuthors) { // chats
 | ||||||
|  |  | ||||||
|  | @ -130,7 +130,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData | ||||||
| 		if (chatPhoto && chatPhoto->date) { | 		if (chatPhoto && chatPhoto->date) { | ||||||
| 			_photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer)); | 			_photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer)); | ||||||
| 		} | 		} | ||||||
| 		if (_peerChannel->isMegagroup() && _peerChannel->mgInfo->lastParticipants.isEmpty()) { | 		if (_peerChannel->isMegagroup() && (_peerChannel->mgInfo->lastParticipants.isEmpty() || (_peerChannel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated) || _peerChannel->lastParticipantsCountOutdated())) { | ||||||
| 			if (App::api()) App::api()->requestLastParticipants(_peerChannel); | 			if (App::api()) App::api()->requestLastParticipants(_peerChannel); | ||||||
| 		} | 		} | ||||||
| 		_peerChannel->updateFull(); | 		_peerChannel->updateFull(); | ||||||
|  | @ -487,7 +487,7 @@ void ProfileInner::onAdmins() { | ||||||
| void ProfileInner::onCreateInvitationLink() { | void ProfileInner::onCreateInvitationLink() { | ||||||
| 	if (!_peerChat && !_peerChannel) return; | 	if (!_peerChat && !_peerChannel) return; | ||||||
| 
 | 
 | ||||||
| 	ConfirmBox *box = new ConfirmBox(lang((_peerChat && _peerChat->invitationUrl.isEmpty()) ? lng_group_invite_about : lng_group_invite_about_new)); | 	ConfirmBox *box = new ConfirmBox(lang(((_peerChat && _peerChat->invitationUrl.isEmpty()) || (_peerChannel && _peerChannel->invitationUrl.isEmpty())) ? lng_group_invite_about : lng_group_invite_about_new)); | ||||||
| 	connect(box, SIGNAL(confirmed()), this, SLOT(onCreateInvitationLinkSure())); | 	connect(box, SIGNAL(confirmed()), this, SLOT(onCreateInvitationLinkSure())); | ||||||
| 	App::wnd()->showLayer(box); | 	App::wnd()->showLayer(box); | ||||||
| } | } | ||||||
|  | @ -686,24 +686,31 @@ void ProfileInner::reorderParticipants() { | ||||||
| 		} | 		} | ||||||
| 		loadProfilePhotos(_lastPreload); | 		loadProfilePhotos(_lastPreload); | ||||||
| 	} else if (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn() && !_peerChannel->mgInfo->lastParticipants.isEmpty()) { | 	} else if (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn() && !_peerChannel->mgInfo->lastParticipants.isEmpty()) { | ||||||
| 		if (!_peerChannel->mgInfo->lastParticipants.isEmpty()) { | 		if (_peerChannel->mgInfo->lastParticipants.isEmpty() || (_peerChannel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated) || _peerChannel->lastParticipantsCountOutdated()) { | ||||||
| 			_participants.clear(); | 			if (App::api()) App::api()->requestLastParticipants(_peerChannel); | ||||||
| 			for (ParticipantsData::iterator i = _participantsData.begin(), e = _participantsData.end(); i != e; ++i) { | 		} else if (!_peerChannel->mgInfo->lastParticipants.isEmpty()) { | ||||||
| 				if (*i) { | 			const MegagroupInfo::LastParticipants &list(_peerChannel->mgInfo->lastParticipants); | ||||||
| 					delete *i; | 			int32 s = list.size(); | ||||||
| 					*i = 0; | 			for (int32 i = 0, l = _participants.size(); i < l; ++i) { | ||||||
|  | 				if (i >= s || _participants.at(i) != list.at(i)) { | ||||||
|  | 					if (_participantsData.at(i)) { | ||||||
|  | 						delete _participantsData.at(i); | ||||||
|  | 						_participantsData[i] = 0; | ||||||
|  | 					} | ||||||
|  | 					if (i < s) { | ||||||
|  | 						_participants[i] = list.at(i); | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			_participants.reserve(_peerChannel->mgInfo->lastParticipants.size()); | 			if (_participants.size() > s) { | ||||||
| 			_participantsData.resize(_peerChannel->mgInfo->lastParticipants.size()); | 				_participants.resize(s); | ||||||
| 		} | 			} else { | ||||||
| 		UserData *self = App::self(); | 				_participants.reserve(s); | ||||||
| 		bool onlyMe = true; | 				for (int32 i = _participants.size(); i < s; ++i) { | ||||||
| 		for (MegagroupInfo::LastParticipants::const_iterator i = _peerChannel->mgInfo->lastParticipants.cbegin(), e = _peerChannel->mgInfo->lastParticipants.cend(); i != e; ++i) { | 					_participants.push_back(list.at(i)); | ||||||
| 			_participants.push_back(*i); | 				} | ||||||
| 		} | 			} | ||||||
| 		if (_peerChannel->mgInfo->lastParticipants.isEmpty()) { | 			_participantsData.resize(s); | ||||||
| 			if (App::api()) App::api()->requestLastParticipants(_peerChannel); |  | ||||||
| 		} | 		} | ||||||
| 		_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status); | 		_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status); | ||||||
| 		loadProfilePhotos(_lastPreload); | 		loadProfilePhotos(_lastPreload); | ||||||
|  | @ -1720,6 +1727,11 @@ void ProfileWidget::onScroll() { | ||||||
| 	if (!_scroll.isHidden() && _scroll.scrollTop() < _scroll.scrollTopMax()) { | 	if (!_scroll.isHidden() && _scroll.scrollTop() < _scroll.scrollTopMax()) { | ||||||
| 		_inner.allowDecreaseHeight(_scroll.scrollTopMax() - _scroll.scrollTop()); | 		_inner.allowDecreaseHeight(_scroll.scrollTopMax() - _scroll.scrollTop()); | ||||||
| 	} | 	} | ||||||
|  | 	if (peer()->isMegagroup() && !peer()->asChannel()->mgInfo->lastParticipants.isEmpty() && peer()->asChannel()->mgInfo->lastParticipants.size() < peer()->asChannel()->count) { | ||||||
|  | 		if (_scroll.scrollTop() + PreloadHeightsCount * _scroll.height() > _scroll.scrollTopMax()) { | ||||||
|  | 			App::api()->requestLastParticipants(peer()->asChannel(), false); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ProfileWidget::resizeEvent(QResizeEvent *e) { | void ProfileWidget::resizeEvent(QResizeEvent *e) { | ||||||
|  |  | ||||||
|  | @ -526,7 +526,7 @@ private: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct MegagroupInfo { | struct MegagroupInfo { | ||||||
| 	MegagroupInfo() : botStatus(-1), migrateFromPtr(0) { | 	MegagroupInfo() : botStatus(-1), migrateFromPtr(0), lastParticipantsStatus(LastParticipantsUpToDate), lastParticipantsCount(0) { | ||||||
| 	} | 	} | ||||||
| 	typedef QList<UserData*> LastParticipants; | 	typedef QList<UserData*> LastParticipants; | ||||||
| 	LastParticipants lastParticipants; | 	LastParticipants lastParticipants; | ||||||
|  | @ -537,6 +537,15 @@ struct MegagroupInfo { | ||||||
| 	typedef QMap<UserData*, bool> Bots; | 	typedef QMap<UserData*, bool> Bots; | ||||||
| 	Bots bots; | 	Bots bots; | ||||||
| 	int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
 | 	int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
 | ||||||
|  | 
 | ||||||
|  | 	enum LastParticipantsStatus { | ||||||
|  | 		LastParticipantsUpToDate       = 0x00, | ||||||
|  | 		LastParticipantsAdminsOutdated = 0x01, | ||||||
|  | 		LastParticipantsCountOutdated  = 0x02, | ||||||
|  | 	}; | ||||||
|  | 	mutable int32 lastParticipantsStatus; | ||||||
|  | 	int32 lastParticipantsCount; | ||||||
|  | 
 | ||||||
| 	ChatData *migrateFromPtr; | 	ChatData *migrateFromPtr; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -563,6 +572,16 @@ public: | ||||||
| 	int32 version; | 	int32 version; | ||||||
| 	int32 flags, flagsFull; | 	int32 flags, flagsFull; | ||||||
| 	MegagroupInfo *mgInfo; | 	MegagroupInfo *mgInfo; | ||||||
|  | 	bool lastParticipantsCountOutdated() const { | ||||||
|  | 		if (!mgInfo || !(mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsCountOutdated)) { | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 		if (mgInfo->lastParticipantsCount == count) { | ||||||
|  | 			mgInfo->lastParticipantsStatus &= ~MegagroupInfo::LastParticipantsCountOutdated; | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
| 	void flagsUpdated(); | 	void flagsUpdated(); | ||||||
| 	bool isMegagroup() const { | 	bool isMegagroup() const { | ||||||
| 		return flags & MTPDchannel::flag_megagroup; | 		return flags & MTPDchannel::flag_megagroup; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue