562 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			562 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
This file is part of Telegram Desktop,
 | 
						|
the official desktop application for the Telegram messaging service.
 | 
						|
 | 
						|
For license and copyright information please follow this link:
 | 
						|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
						|
*/
 | 
						|
#include "data/data_channel.h"
 | 
						|
 | 
						|
#include "data/data_peer_values.h"
 | 
						|
#include "data/data_channel_admins.h"
 | 
						|
#include "data/data_user.h"
 | 
						|
#include "data/data_chat.h"
 | 
						|
#include "data/data_session.h"
 | 
						|
#include "data/data_feed.h"
 | 
						|
#include "observer_peer.h"
 | 
						|
#include "auth_session.h"
 | 
						|
#include "apiwrap.h"
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
using UpdateFlag = Notify::PeerUpdate::Flag;
 | 
						|
 | 
						|
} // namespace
 | 
						|
 | 
						|
ChatData *MegagroupInfo::getMigrateFromChat() const {
 | 
						|
	return _migratedFrom;
 | 
						|
}
 | 
						|
 | 
						|
void MegagroupInfo::setMigrateFromChat(ChatData *chat) {
 | 
						|
	_migratedFrom = chat;
 | 
						|
}
 | 
						|
 | 
						|
ChannelData::ChannelData(not_null<Data::Session*> owner, PeerId id)
 | 
						|
: PeerData(owner, id)
 | 
						|
, inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))) {
 | 
						|
	Data::PeerFlagValue(
 | 
						|
		this,
 | 
						|
		MTPDchannel::Flag::f_megagroup
 | 
						|
	) | rpl::start_with_next([=](bool megagroup) {
 | 
						|
		if (megagroup) {
 | 
						|
			if (!mgInfo) {
 | 
						|
				mgInfo = std::make_unique<MegagroupInfo>();
 | 
						|
			}
 | 
						|
		} else if (mgInfo) {
 | 
						|
			mgInfo = nullptr;
 | 
						|
		}
 | 
						|
	}, _lifetime);
 | 
						|
 | 
						|
	Data::PeerFlagsValue(
 | 
						|
		this,
 | 
						|
		MTPDchannel::Flag::f_left | MTPDchannel_ClientFlag::f_forbidden
 | 
						|
	) | rpl::distinct_until_changed(
 | 
						|
	) | rpl::start_with_next([=] {
 | 
						|
		if (const auto chat = getMigrateFromChat()) {
 | 
						|
			Notify::peerUpdatedDelayed(chat, UpdateFlag::MigrationChanged);
 | 
						|
			Notify::peerUpdatedDelayed(this, UpdateFlag::MigrationChanged);
 | 
						|
		}
 | 
						|
	}, _lifetime);
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setPhoto(const MTPChatPhoto &photo) {
 | 
						|
	setPhoto(userpicPhotoId(), photo);
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setPhoto(PhotoId photoId, const MTPChatPhoto &photo) {
 | 
						|
	photo.match([&](const MTPDchatPhoto & data) {
 | 
						|
		updateUserpic(photoId, data.vdc_id.v, data.vphoto_small);
 | 
						|
	}, [&](const MTPDchatPhotoEmpty &) {
 | 
						|
		clearUserpic();
 | 
						|
	});
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setName(const QString &newName, const QString &newUsername) {
 | 
						|
	updateNameDelayed(newName.isEmpty() ? name : newName, QString(), newUsername);
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setInviteLink(const QString &newInviteLink) {
 | 
						|
	if (newInviteLink != _inviteLink) {
 | 
						|
		_inviteLink = newInviteLink;
 | 
						|
		Notify::peerUpdatedDelayed(this, UpdateFlag::InviteLinkChanged);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
QString ChannelData::inviteLink() const {
 | 
						|
	return _inviteLink;
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canHaveInviteLink() const {
 | 
						|
	return (adminRights() & AdminRight::f_invite_users)
 | 
						|
		|| amCreator();
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setMembersCount(int newMembersCount) {
 | 
						|
	if (_membersCount != newMembersCount) {
 | 
						|
		if (isMegagroup() && !mgInfo->lastParticipants.empty()) {
 | 
						|
			mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
 | 
						|
			mgInfo->lastParticipantsCount = membersCount();
 | 
						|
		}
 | 
						|
		_membersCount = newMembersCount;
 | 
						|
		Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::MembersChanged);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setAdminsCount(int newAdminsCount) {
 | 
						|
	if (_adminsCount != newAdminsCount) {
 | 
						|
		_adminsCount = newAdminsCount;
 | 
						|
		Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::AdminsChanged);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setRestrictedCount(int newRestrictedCount) {
 | 
						|
	if (_restrictedCount != newRestrictedCount) {
 | 
						|
		_restrictedCount = newRestrictedCount;
 | 
						|
		Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::BannedUsersChanged);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setKickedCount(int newKickedCount) {
 | 
						|
	if (_kickedCount != newKickedCount) {
 | 
						|
		_kickedCount = newKickedCount;
 | 
						|
		Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::BannedUsersChanged);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
MTPChatBannedRights ChannelData::KickedRestrictedRights() {
 | 
						|
	using Flag = MTPDchatBannedRights::Flag;
 | 
						|
	const auto flags = Flag::f_view_messages
 | 
						|
		| Flag::f_send_messages
 | 
						|
		| Flag::f_send_media
 | 
						|
		| Flag::f_embed_links
 | 
						|
		| Flag::f_send_stickers
 | 
						|
		| Flag::f_send_gifs
 | 
						|
		| Flag::f_send_games
 | 
						|
		| Flag::f_send_inline;
 | 
						|
	return MTP_chatBannedRights(
 | 
						|
		MTP_flags(flags),
 | 
						|
		MTP_int(std::numeric_limits<int32>::max()));
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::applyEditAdmin(
 | 
						|
		not_null<UserData*> user,
 | 
						|
		const MTPChatAdminRights &oldRights,
 | 
						|
		const MTPChatAdminRights &newRights) {
 | 
						|
	if (mgInfo) {
 | 
						|
		// If rights are empty - still add participant? TODO check
 | 
						|
		if (!base::contains(mgInfo->lastParticipants, user)) {
 | 
						|
			mgInfo->lastParticipants.push_front(user);
 | 
						|
			setMembersCount(membersCount() + 1);
 | 
						|
			if (user->botInfo && !mgInfo->bots.contains(user)) {
 | 
						|
				mgInfo->bots.insert(user);
 | 
						|
				if (mgInfo->botStatus != 0 && mgInfo->botStatus < 2) {
 | 
						|
					mgInfo->botStatus = 2;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		// If rights are empty - still remove restrictions? TODO check
 | 
						|
		if (mgInfo->lastRestricted.contains(user)) {
 | 
						|
			mgInfo->lastRestricted.remove(user);
 | 
						|
			if (restrictedCount() > 0) {
 | 
						|
				setRestrictedCount(restrictedCount() - 1);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		auto userId = peerToUser(user->id);
 | 
						|
		auto it = mgInfo->lastAdmins.find(user);
 | 
						|
		if (newRights.c_chatAdminRights().vflags.v != 0) {
 | 
						|
			auto lastAdmin = MegagroupInfo::Admin { newRights };
 | 
						|
			lastAdmin.canEdit = true;
 | 
						|
			if (it == mgInfo->lastAdmins.cend()) {
 | 
						|
				mgInfo->lastAdmins.emplace(user, lastAdmin);
 | 
						|
				setAdminsCount(adminsCount() + 1);
 | 
						|
			} else {
 | 
						|
				it->second = lastAdmin;
 | 
						|
			}
 | 
						|
			Data::ChannelAdminChanges(this).feed(userId, true);
 | 
						|
		} else {
 | 
						|
			if (it != mgInfo->lastAdmins.cend()) {
 | 
						|
				mgInfo->lastAdmins.erase(it);
 | 
						|
				if (adminsCount() > 0) {
 | 
						|
					setAdminsCount(adminsCount() - 1);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			Data::ChannelAdminChanges(this).feed(userId, false);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if (oldRights.c_chatAdminRights().vflags.v && !newRights.c_chatAdminRights().vflags.v) {
 | 
						|
		// We removed an admin.
 | 
						|
		if (adminsCount() > 1) {
 | 
						|
			setAdminsCount(adminsCount() - 1);
 | 
						|
		}
 | 
						|
		if (!isMegagroup() && user->botInfo && membersCount() > 1) {
 | 
						|
			// Removing bot admin removes it from channel.
 | 
						|
			setMembersCount(membersCount() - 1);
 | 
						|
		}
 | 
						|
	} else if (!oldRights.c_chatAdminRights().vflags.v && newRights.c_chatAdminRights().vflags.v) {
 | 
						|
		// We added an admin.
 | 
						|
		setAdminsCount(adminsCount() + 1);
 | 
						|
		updateFullForced();
 | 
						|
	}
 | 
						|
	Notify::peerUpdatedDelayed(
 | 
						|
		this,
 | 
						|
		Notify::PeerUpdate::Flag::AdminsChanged);
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::applyEditBanned(not_null<UserData*> user, const MTPChatBannedRights &oldRights, const MTPChatBannedRights &newRights) {
 | 
						|
	auto flags = Notify::PeerUpdate::Flag::BannedUsersChanged | Notify::PeerUpdate::Flag::None;
 | 
						|
	auto isKicked = (newRights.c_chatBannedRights().vflags.v & MTPDchatBannedRights::Flag::f_view_messages);
 | 
						|
	auto isRestricted = !isKicked && (newRights.c_chatBannedRights().vflags.v != 0);
 | 
						|
	if (mgInfo) {
 | 
						|
		// If rights are empty - still remove admin? TODO check
 | 
						|
		if (mgInfo->lastAdmins.contains(user)) {
 | 
						|
			mgInfo->lastAdmins.remove(user);
 | 
						|
			if (adminsCount() > 1) {
 | 
						|
				setAdminsCount(adminsCount() - 1);
 | 
						|
			} else {
 | 
						|
				flags |= Notify::PeerUpdate::Flag::AdminsChanged;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		auto it = mgInfo->lastRestricted.find(user);
 | 
						|
		if (isRestricted) {
 | 
						|
			if (it == mgInfo->lastRestricted.cend()) {
 | 
						|
				mgInfo->lastRestricted.emplace(user, MegagroupInfo::Restricted { newRights });
 | 
						|
				setRestrictedCount(restrictedCount() + 1);
 | 
						|
			} else {
 | 
						|
				it->second.rights = newRights;
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			if (it != mgInfo->lastRestricted.cend()) {
 | 
						|
				mgInfo->lastRestricted.erase(it);
 | 
						|
				if (restrictedCount() > 0) {
 | 
						|
					setRestrictedCount(restrictedCount() - 1);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			if (isKicked) {
 | 
						|
				auto i = ranges::find(mgInfo->lastParticipants, user);
 | 
						|
				if (i != mgInfo->lastParticipants.end()) {
 | 
						|
					mgInfo->lastParticipants.erase(i);
 | 
						|
				}
 | 
						|
				if (membersCount() > 1) {
 | 
						|
					setMembersCount(membersCount() - 1);
 | 
						|
				} else {
 | 
						|
					mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
 | 
						|
					mgInfo->lastParticipantsCount = 0;
 | 
						|
				}
 | 
						|
				setKickedCount(kickedCount() + 1);
 | 
						|
				if (mgInfo->bots.contains(user)) {
 | 
						|
					mgInfo->bots.remove(user);
 | 
						|
					if (mgInfo->bots.empty() && mgInfo->botStatus > 0) {
 | 
						|
						mgInfo->botStatus = -1;
 | 
						|
					}
 | 
						|
				}
 | 
						|
				flags |= Notify::PeerUpdate::Flag::MembersChanged;
 | 
						|
				owner().removeMegagroupParticipant(this, user);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		Data::ChannelAdminChanges(this).feed(peerToUser(user->id), false);
 | 
						|
	} else {
 | 
						|
		if (isKicked) {
 | 
						|
			if (membersCount() > 1) {
 | 
						|
				setMembersCount(membersCount() - 1);
 | 
						|
				flags |= Notify::PeerUpdate::Flag::MembersChanged;
 | 
						|
			}
 | 
						|
			setKickedCount(kickedCount() + 1);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	Notify::peerUpdatedDelayed(this, flags);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::isGroupAdmin(not_null<UserData*> user) const {
 | 
						|
	if (auto info = mgInfo.get()) {
 | 
						|
		return info->admins.contains(peerToUser(user->id));
 | 
						|
	}
 | 
						|
	return false;
 | 
						|
}
 | 
						|
 | 
						|
QString ChannelData::unavailableReason() const {
 | 
						|
	return _unavailableReason;
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setUnavailableReason(const QString &text) {
 | 
						|
	if (_unavailableReason != text) {
 | 
						|
		_unavailableReason = text;
 | 
						|
		Notify::peerUpdatedDelayed(
 | 
						|
			this,
 | 
						|
			Notify::PeerUpdate::Flag::UnavailableReasonChanged);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setAvailableMinId(MsgId availableMinId) {
 | 
						|
	if (_availableMinId != availableMinId) {
 | 
						|
		_availableMinId = availableMinId;
 | 
						|
		if (pinnedMessageId() <= _availableMinId) {
 | 
						|
			clearPinnedMessage();
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setFeed(not_null<Data::Feed*> feed) {
 | 
						|
	setFeedPointer(feed);
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::clearFeed() {
 | 
						|
	setFeedPointer(nullptr);
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setFeedPointer(Data::Feed *feed) {
 | 
						|
	if (_feed != feed) {
 | 
						|
		const auto was = _feed;
 | 
						|
		_feed = feed;
 | 
						|
		if (was) {
 | 
						|
			was->unregisterOne(this);
 | 
						|
		}
 | 
						|
		if (_feed) {
 | 
						|
			_feed->registerOne(this);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canBanMembers() const {
 | 
						|
	return amCreator()
 | 
						|
		|| (adminRights() & AdminRight::f_ban_users);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canEditMessages() const {
 | 
						|
	return amCreator()
 | 
						|
		|| (adminRights() & AdminRight::f_edit_messages);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canDeleteMessages() const {
 | 
						|
	return amCreator()
 | 
						|
		|| (adminRights() & AdminRight::f_delete_messages);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::anyoneCanAddMembers() const {
 | 
						|
	return !(defaultRestrictions() & Restriction::f_invite_users);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::hiddenPreHistory() const {
 | 
						|
	return (fullFlags() & MTPDchannelFull::Flag::f_hidden_prehistory);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canAddMembers() const {
 | 
						|
	return isMegagroup()
 | 
						|
		? !amRestricted(ChatRestriction::f_invite_users)
 | 
						|
		: ((adminRights() & AdminRight::f_invite_users) || amCreator());
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canSendPolls() const {
 | 
						|
	return canWrite() && !amRestricted(ChatRestriction::f_send_polls);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canAddAdmins() const {
 | 
						|
	return amCreator()
 | 
						|
		|| (adminRights() & AdminRight::f_add_admins);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canPublish() const {
 | 
						|
	return amCreator()
 | 
						|
		|| (adminRights() & AdminRight::f_post_messages);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canWrite() const {
 | 
						|
	// Duplicated in Data::CanWriteValue().
 | 
						|
	return amIn()
 | 
						|
		&& (canPublish()
 | 
						|
			|| (!isBroadcast()
 | 
						|
				&& !amRestricted(Restriction::f_send_messages)));
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canViewMembers() const {
 | 
						|
	return fullFlags()
 | 
						|
		& MTPDchannelFull::Flag::f_can_view_participants;
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canViewAdmins() const {
 | 
						|
	return (isMegagroup() || hasAdminRights() || amCreator());
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canViewBanned() const {
 | 
						|
	return (hasAdminRights() || amCreator());
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canEditInformation() const {
 | 
						|
	return isMegagroup()
 | 
						|
		? !amRestricted(Restriction::f_change_info)
 | 
						|
		: ((adminRights() & AdminRight::f_change_info) || amCreator());
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canEditPermissions() const {
 | 
						|
	return isMegagroup()
 | 
						|
		&& ((adminRights() & AdminRight::f_ban_users) || amCreator());
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canEditSignatures() const {
 | 
						|
	return isChannel() && canEditInformation();
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canEditPreHistoryHidden() const {
 | 
						|
	return isMegagroup()
 | 
						|
		&& ((adminRights() & AdminRight::f_ban_users) || amCreator())
 | 
						|
		&& (!isPublic() || canEditUsername());
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canEditUsername() const {
 | 
						|
	return amCreator()
 | 
						|
		&& (fullFlags() & MTPDchannelFull::Flag::f_can_set_username);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canEditStickers() const {
 | 
						|
	return (fullFlags() & MTPDchannelFull::Flag::f_can_set_stickers);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canDelete() const {
 | 
						|
	constexpr auto kDeleteChannelMembersLimit = 1000;
 | 
						|
	return amCreator()
 | 
						|
		&& (membersCount() <= kDeleteChannelMembersLimit);
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canEditLastAdmin(not_null<UserData*> user) const {
 | 
						|
	// Duplicated in ParticipantsBoxController::canEditAdmin :(
 | 
						|
	if (mgInfo) {
 | 
						|
		auto i = mgInfo->lastAdmins.find(user);
 | 
						|
		if (i != mgInfo->lastAdmins.cend()) {
 | 
						|
			return i->second.canEdit;
 | 
						|
		}
 | 
						|
		return (user != mgInfo->creator);
 | 
						|
	}
 | 
						|
	return false;
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canEditAdmin(not_null<UserData*> user) const {
 | 
						|
	// Duplicated in ParticipantsBoxController::canEditAdmin :(
 | 
						|
	if (user->isSelf()) {
 | 
						|
		return false;
 | 
						|
	} else if (amCreator()) {
 | 
						|
		return true;
 | 
						|
	} else if (!canEditLastAdmin(user)) {
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
	return adminRights() & AdminRight::f_add_admins;
 | 
						|
}
 | 
						|
 | 
						|
bool ChannelData::canRestrictUser(not_null<UserData*> user) const {
 | 
						|
	// Duplicated in ParticipantsBoxController::canRestrictUser :(
 | 
						|
	if (user->isSelf()) {
 | 
						|
		return false;
 | 
						|
	} else if (amCreator()) {
 | 
						|
		return true;
 | 
						|
	} else if (!canEditLastAdmin(user)) {
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
	return adminRights() & AdminRight::f_ban_users;
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setAdminRights(const MTPChatAdminRights &rights) {
 | 
						|
	if (rights.c_chatAdminRights().vflags.v == adminRights()) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	_adminRights.set(rights.c_chatAdminRights().vflags.v);
 | 
						|
	if (isMegagroup()) {
 | 
						|
		const auto self = session().user();
 | 
						|
		if (hasAdminRights()) {
 | 
						|
			if (!amCreator()) {
 | 
						|
				auto me = MegagroupInfo::Admin { rights };
 | 
						|
				me.canEdit = false;
 | 
						|
				mgInfo->lastAdmins.emplace(self, me);
 | 
						|
			}
 | 
						|
			mgInfo->lastRestricted.remove(self);
 | 
						|
		} else {
 | 
						|
			mgInfo->lastAdmins.remove(self);
 | 
						|
		}
 | 
						|
 | 
						|
		auto amAdmin = hasAdminRights() || amCreator();
 | 
						|
		Data::ChannelAdminChanges(this).feed(session().userId(), amAdmin);
 | 
						|
	}
 | 
						|
	Notify::peerUpdatedDelayed(this, UpdateFlag::RightsChanged | UpdateFlag::AdminsChanged | UpdateFlag::BannedUsersChanged);
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setRestrictions(const MTPChatBannedRights &rights) {
 | 
						|
	if (rights.c_chatBannedRights().vflags.v == restrictions()
 | 
						|
		&& rights.c_chatBannedRights().vuntil_date.v == _restrictedUntil) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	_restrictedUntil = rights.c_chatBannedRights().vuntil_date.v;
 | 
						|
	_restrictions.set(rights.c_chatBannedRights().vflags.v);
 | 
						|
	if (isMegagroup()) {
 | 
						|
		const auto self = session().user();
 | 
						|
		if (hasRestrictions()) {
 | 
						|
			if (!amCreator()) {
 | 
						|
				auto me = MegagroupInfo::Restricted { rights };
 | 
						|
				mgInfo->lastRestricted.emplace(self, me);
 | 
						|
			}
 | 
						|
			mgInfo->lastAdmins.remove(self);
 | 
						|
			Data::ChannelAdminChanges(this).feed(session().userId(), false);
 | 
						|
		} else {
 | 
						|
			mgInfo->lastRestricted.remove(self);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	Notify::peerUpdatedDelayed(this, UpdateFlag::RightsChanged | UpdateFlag::AdminsChanged | UpdateFlag::BannedUsersChanged);
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setDefaultRestrictions(const MTPChatBannedRights &rights) {
 | 
						|
	if (rights.c_chatBannedRights().vflags.v == defaultRestrictions()) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	_defaultRestrictions.set(rights.c_chatBannedRights().vflags.v);
 | 
						|
	Notify::peerUpdatedDelayed(this, UpdateFlag::RightsChanged);
 | 
						|
}
 | 
						|
 | 
						|
auto ChannelData::applyUpdateVersion(int version) -> UpdateStatus {
 | 
						|
	if (_version > version) {
 | 
						|
		return UpdateStatus::TooOld;
 | 
						|
	} else if (_version + 1 < version) {
 | 
						|
		session().api().requestPeer(this);
 | 
						|
		return UpdateStatus::Skipped;
 | 
						|
	}
 | 
						|
	setVersion(version);
 | 
						|
	return UpdateStatus::Good;
 | 
						|
}
 | 
						|
 | 
						|
ChatData *ChannelData::getMigrateFromChat() const {
 | 
						|
	if (const auto info = mgInfo.get()) {
 | 
						|
		return info->getMigrateFromChat();
 | 
						|
	}
 | 
						|
	return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
void ChannelData::setMigrateFromChat(ChatData *chat) {
 | 
						|
	Expects(mgInfo != nullptr);
 | 
						|
 | 
						|
	const auto info = mgInfo.get();
 | 
						|
	if (chat != info->getMigrateFromChat()) {
 | 
						|
		info->setMigrateFromChat(chat);
 | 
						|
		if (amIn()) {
 | 
						|
			Notify::peerUpdatedDelayed(this, UpdateFlag::MigrationChanged);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
namespace Data {
 | 
						|
 | 
						|
void ApplyMigration(
 | 
						|
		not_null<ChatData*> chat,
 | 
						|
		not_null<ChannelData*> channel) {
 | 
						|
	Expects(channel->isMegagroup());
 | 
						|
 | 
						|
	chat->setMigrateToChannel(channel);
 | 
						|
	channel->setMigrateFromChat(chat);
 | 
						|
}
 | 
						|
 | 
						|
void ApplyChannelUpdate(
 | 
						|
		not_null<ChannelData*> channel,
 | 
						|
		const MTPDupdateChatDefaultBannedRights &update) {
 | 
						|
	if (channel->applyUpdateVersion(update.vversion.v)
 | 
						|
		!= ChannelData::UpdateStatus::Good) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	channel->setDefaultRestrictions(update.vdefault_banned_rights);
 | 
						|
}
 | 
						|
 | 
						|
} // namespace Data
 |