mirror of https://github.com/procxx/kepka.git
				
				
				
			Edit pre-history visibility in megagroups.
This commit is contained in:
		
							parent
							
								
									2387b66e86
								
							
						
					
					
						commit
						542ba89f25
					
				|  | @ -668,6 +668,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org | ||||||
| "lng_manage_peer_administrators" = "Administrators"; | "lng_manage_peer_administrators" = "Administrators"; | ||||||
| "lng_manage_peer_banned_users" = "Banned users"; | "lng_manage_peer_banned_users" = "Banned users"; | ||||||
| "lng_manage_peer_restricted_users" = "Restricted users"; | "lng_manage_peer_restricted_users" = "Restricted users"; | ||||||
|  | "lng_manage_history_visibility_title" = "Chat history for new members"; | ||||||
|  | "lng_manage_history_visibility_shown" = "Visible"; | ||||||
|  | "lng_manage_history_visibility_shown_about" = "New members will see messages that were sent before they joined."; | ||||||
|  | "lng_manage_history_visibility_hidden" = "Hidden"; | ||||||
|  | "lng_manage_history_visibility_hidden_about" = "New members won't see earlier messages."; | ||||||
| 
 | 
 | ||||||
| "lng_report_title" = "Report channel"; | "lng_report_title" = "Report channel"; | ||||||
| "lng_report_group_title" = "Report group"; | "lng_report_group_title" = "Report group"; | ||||||
|  |  | ||||||
|  | @ -736,13 +736,11 @@ void ApiWrap::applyLastParticipantsList( | ||||||
| 	if (!keyboardBotFound) { | 	if (!keyboardBotFound) { | ||||||
| 		h->clearLastKeyboard(); | 		h->clearLastKeyboard(); | ||||||
| 	} | 	} | ||||||
| 	int newMembersCount = qMax(fullCount, list.size()); |  | ||||||
| 	if (newMembersCount > peer->membersCount()) { |  | ||||||
| 		peer->setMembersCount(newMembersCount); |  | ||||||
| 	} |  | ||||||
| 	if (!bots) { | 	if (!bots) { | ||||||
| 		if (list.isEmpty()) { | 		if (list.isEmpty()) { | ||||||
| 			peer->setMembersCount(peer->mgInfo->lastParticipants.size()); | 			peer->setMembersCount(peer->mgInfo->lastParticipants.size()); | ||||||
|  | 		} else { | ||||||
|  | 			peer->setMembersCount(fullCount); | ||||||
| 		} | 		} | ||||||
| 		Notify::PeerUpdate update(peer); | 		Notify::PeerUpdate update(peer); | ||||||
| 		update.flags |= Notify::PeerUpdate::Flag::MembersChanged | Notify::PeerUpdate::Flag::AdminsChanged; | 		update.flags |= Notify::PeerUpdate::Flag::MembersChanged | Notify::PeerUpdate::Flag::AdminsChanged; | ||||||
|  |  | ||||||
|  | @ -69,6 +69,10 @@ private: | ||||||
| 		Everyone, | 		Everyone, | ||||||
| 		OnlyAdmins, | 		OnlyAdmins, | ||||||
| 	}; | 	}; | ||||||
|  | 	enum class HistoryVisibility { | ||||||
|  | 		Visible, | ||||||
|  | 		Hidden, | ||||||
|  | 	}; | ||||||
| 	enum class UsernameState { | 	enum class UsernameState { | ||||||
| 		Normal, | 		Normal, | ||||||
| 		TooMany, | 		TooMany, | ||||||
|  | @ -90,6 +94,9 @@ private: | ||||||
| 		Ui::SlideWrap<Ui::RpWidget> *editInviteLinkWrap = nullptr; | 		Ui::SlideWrap<Ui::RpWidget> *editInviteLinkWrap = nullptr; | ||||||
| 		Ui::FlatLabel *inviteLink = nullptr; | 		Ui::FlatLabel *inviteLink = nullptr; | ||||||
| 
 | 
 | ||||||
|  | 		std::shared_ptr<Ui::RadioenumGroup<HistoryVisibility>> historyVisibility; | ||||||
|  | 		Ui::SlideWrap<Ui::RpWidget> *historyVisibilityWrap = nullptr; | ||||||
|  | 
 | ||||||
| 		std::shared_ptr<Ui::RadioenumGroup<Invites>> invites; | 		std::shared_ptr<Ui::RadioenumGroup<Invites>> invites; | ||||||
| 		Ui::Checkbox *signatures = nullptr; | 		Ui::Checkbox *signatures = nullptr; | ||||||
| 	}; | 	}; | ||||||
|  | @ -97,6 +104,7 @@ private: | ||||||
| 		base::optional<QString> username; | 		base::optional<QString> username; | ||||||
| 		base::optional<QString> title; | 		base::optional<QString> title; | ||||||
| 		base::optional<QString> description; | 		base::optional<QString> description; | ||||||
|  | 		base::optional<bool> hiddenPreHistory; | ||||||
| 		base::optional<bool> signatures; | 		base::optional<bool> signatures; | ||||||
| 		base::optional<bool> everyoneInvites; | 		base::optional<bool> everyoneInvites; | ||||||
| 	}; | 	}; | ||||||
|  | @ -110,6 +118,7 @@ private: | ||||||
| 	object_ptr<Ui::RpWidget> createUsernameEdit(); | 	object_ptr<Ui::RpWidget> createUsernameEdit(); | ||||||
| 	object_ptr<Ui::RpWidget> createInviteLinkCreate(); | 	object_ptr<Ui::RpWidget> createInviteLinkCreate(); | ||||||
| 	object_ptr<Ui::RpWidget> createInviteLinkEdit(); | 	object_ptr<Ui::RpWidget> createInviteLinkEdit(); | ||||||
|  | 	object_ptr<Ui::RpWidget> createHistoryVisibilityEdit(); | ||||||
| 	object_ptr<Ui::RpWidget> createSignaturesEdit(); | 	object_ptr<Ui::RpWidget> createSignaturesEdit(); | ||||||
| 	object_ptr<Ui::RpWidget> createInvitesEdit(); | 	object_ptr<Ui::RpWidget> createInvitesEdit(); | ||||||
| 	object_ptr<Ui::RpWidget> createDeleteButton(); | 	object_ptr<Ui::RpWidget> createDeleteButton(); | ||||||
|  | @ -132,6 +141,7 @@ private: | ||||||
| 	bool inviteLinkShown() const; | 	bool inviteLinkShown() const; | ||||||
| 	void refreshEditInviteLink(); | 	void refreshEditInviteLink(); | ||||||
| 	void refreshCreateInviteLink(); | 	void refreshCreateInviteLink(); | ||||||
|  | 	void refreshHistoryVisibility(); | ||||||
| 	void createInviteLink(); | 	void createInviteLink(); | ||||||
| 	void revokeInviteLink(); | 	void revokeInviteLink(); | ||||||
| 	void exportInviteLink(const QString &confirmation); | 	void exportInviteLink(const QString &confirmation); | ||||||
|  | @ -140,6 +150,7 @@ private: | ||||||
| 	bool validateUsername(Saving &to) const; | 	bool validateUsername(Saving &to) const; | ||||||
| 	bool validateTitle(Saving &to) const; | 	bool validateTitle(Saving &to) const; | ||||||
| 	bool validateDescription(Saving &to) const; | 	bool validateDescription(Saving &to) const; | ||||||
|  | 	bool validateHistoryVisibility(Saving &to) const; | ||||||
| 	bool validateInvites(Saving &to) const; | 	bool validateInvites(Saving &to) const; | ||||||
| 	bool validateSignatures(Saving &to) const; | 	bool validateSignatures(Saving &to) const; | ||||||
| 
 | 
 | ||||||
|  | @ -147,6 +158,7 @@ private: | ||||||
| 	void saveUsername(); | 	void saveUsername(); | ||||||
| 	void saveTitle(); | 	void saveTitle(); | ||||||
| 	void saveDescription(); | 	void saveDescription(); | ||||||
|  | 	void saveHistoryVisibility(); | ||||||
| 	void saveInvites(); | 	void saveInvites(); | ||||||
| 	void saveSignatures(); | 	void saveSignatures(); | ||||||
| 	void savePhoto(); | 	void savePhoto(); | ||||||
|  | @ -202,6 +214,7 @@ object_ptr<Ui::VerticalLayout> Controller::createContent() { | ||||||
| 	_wrap->add(createPrivaciesEdit()); | 	_wrap->add(createPrivaciesEdit()); | ||||||
| 	_wrap->add(createInviteLinkCreate()); | 	_wrap->add(createInviteLinkCreate()); | ||||||
| 	_wrap->add(createInviteLinkEdit()); | 	_wrap->add(createInviteLinkEdit()); | ||||||
|  | 	_wrap->add(createHistoryVisibilityEdit()); | ||||||
| 	_wrap->add(createSignaturesEdit()); | 	_wrap->add(createSignaturesEdit()); | ||||||
| 	_wrap->add(createInvitesEdit()); | 	_wrap->add(createInvitesEdit()); | ||||||
| 	_wrap->add(createDeleteButton()); | 	_wrap->add(createDeleteButton()); | ||||||
|  | @ -435,6 +448,7 @@ void Controller::privacyChanged(Privacy value) { | ||||||
| 		} | 		} | ||||||
| 		refreshCreateInviteLink(); | 		refreshCreateInviteLink(); | ||||||
| 		refreshEditInviteLink(); | 		refreshEditInviteLink(); | ||||||
|  | 		refreshHistoryVisibility(); | ||||||
| 		if (value == Privacy::Public) { | 		if (value == Privacy::Public) { | ||||||
| 			_controls.usernameResult = nullptr; | 			_controls.usernameResult = nullptr; | ||||||
| 			checkUsernameAvailability(); | 			checkUsernameAvailability(); | ||||||
|  | @ -709,14 +723,25 @@ object_ptr<Ui::RpWidget> Controller::createInviteLinkCreate() { | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	auto result = object_ptr<Ui::SlideWrap<Ui::LinkButton>>( | 	auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>( | ||||||
| 		_wrap, | 		_wrap, | ||||||
| 		object_ptr<Ui::LinkButton>( | 		object_ptr<Ui::VerticalLayout>(_wrap), | ||||||
| 			_wrap, |  | ||||||
| 			lang(lng_group_invite_create), |  | ||||||
| 			st::editPeerInviteLinkButton), |  | ||||||
| 		st::editPeerInviteLinkMargins); | 		st::editPeerInviteLinkMargins); | ||||||
| 	result->entity()->addClickHandler([this] { | 	auto container = result->entity(); | ||||||
|  | 
 | ||||||
|  | 	container->add(object_ptr<Ui::FlatLabel>( | ||||||
|  | 		container, | ||||||
|  | 		Lang::Viewer(lng_profile_invite_link_section), | ||||||
|  | 		st::editPeerSectionLabel)); | ||||||
|  | 	container->add(object_ptr<Ui::FixedHeightWidget>( | ||||||
|  | 		container, | ||||||
|  | 		st::editPeerInviteLinkSkip)); | ||||||
|  | 
 | ||||||
|  | 	container->add(object_ptr<Ui::LinkButton>( | ||||||
|  | 		_wrap, | ||||||
|  | 		lang(lng_group_invite_create), | ||||||
|  | 		st::editPeerInviteLinkButton) | ||||||
|  | 	)->addClickHandler([this] { | ||||||
| 		createInviteLink(); | 		createInviteLink(); | ||||||
| 	}); | 	}); | ||||||
| 	_controls.createInviteLinkWrap = result.data(); | 	_controls.createInviteLinkWrap = result.data(); | ||||||
|  | @ -738,10 +763,80 @@ void Controller::refreshCreateInviteLink() { | ||||||
| 		anim::type::instant); | 		anim::type::instant); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | object_ptr<Ui::RpWidget> Controller::createHistoryVisibilityEdit() { | ||||||
|  | 	Expects(_wrap != nullptr); | ||||||
|  | 
 | ||||||
|  | 	if (!_channel->canEditPreHistoryHidden() | ||||||
|  | 		|| !_channel->isMegagroup()) { | ||||||
|  | 		return nullptr; | ||||||
|  | 	} | ||||||
|  | 	auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>( | ||||||
|  | 		_wrap, | ||||||
|  | 		object_ptr<Ui::VerticalLayout>(_wrap), | ||||||
|  | 		st::editPeerInvitesMargins); | ||||||
|  | 	_controls.historyVisibilityWrap = result.data(); | ||||||
|  | 	auto container = result->entity(); | ||||||
|  | 
 | ||||||
|  | 	_controls.historyVisibility | ||||||
|  | 		= std::make_shared<Ui::RadioenumGroup<HistoryVisibility>>( | ||||||
|  | 			_channel->hiddenPreHistory() | ||||||
|  | 				? HistoryVisibility::Hidden | ||||||
|  | 				: HistoryVisibility::Visible); | ||||||
|  | 	auto addButton = [&]( | ||||||
|  | 			HistoryVisibility value, | ||||||
|  | 			LangKey groupTextKey, | ||||||
|  | 			LangKey groupAboutKey) { | ||||||
|  | 		container->add(object_ptr<Ui::FixedHeightWidget>( | ||||||
|  | 			container, | ||||||
|  | 			st::editPeerPrivacyTopSkip + st::editPeerPrivacyBottomSkip)); | ||||||
|  | 		container->add(object_ptr<Ui::Radioenum<HistoryVisibility>>( | ||||||
|  | 			container, | ||||||
|  | 			_controls.historyVisibility, | ||||||
|  | 			value, | ||||||
|  | 			lang(groupTextKey), | ||||||
|  | 			st::defaultBoxCheckbox)); | ||||||
|  | 		container->add(object_ptr<Ui::PaddingWrap<Ui::FlatLabel>>( | ||||||
|  | 			container, | ||||||
|  | 			object_ptr<Ui::FlatLabel>( | ||||||
|  | 				container, | ||||||
|  | 				Lang::Viewer(groupAboutKey), | ||||||
|  | 				st::editPeerPrivacyLabel), | ||||||
|  | 			st::editPeerPrivacyLabelMargins)); | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	container->add(object_ptr<Ui::FlatLabel>( | ||||||
|  | 		container, | ||||||
|  | 		Lang::Viewer(lng_manage_history_visibility_title), | ||||||
|  | 		st::editPeerSectionLabel)); | ||||||
|  | 	addButton( | ||||||
|  | 		HistoryVisibility::Visible, | ||||||
|  | 		lng_manage_history_visibility_shown, | ||||||
|  | 		lng_manage_history_visibility_shown_about); | ||||||
|  | 	addButton( | ||||||
|  | 		HistoryVisibility::Hidden, | ||||||
|  | 		lng_manage_history_visibility_hidden, | ||||||
|  | 		lng_manage_history_visibility_hidden_about); | ||||||
|  | 
 | ||||||
|  | 	refreshHistoryVisibility(); | ||||||
|  | 
 | ||||||
|  | 	return std::move(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Controller::refreshHistoryVisibility() { | ||||||
|  | 	if (!_controls.historyVisibilityWrap) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	auto historyVisibilityShown = !_controls.privacy | ||||||
|  | 		|| (_controls.privacy->value() == Privacy::Private); | ||||||
|  | 	_controls.historyVisibilityWrap->toggle( | ||||||
|  | 		historyVisibilityShown, | ||||||
|  | 		anim::type::instant); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| object_ptr<Ui::RpWidget> Controller::createSignaturesEdit() { | object_ptr<Ui::RpWidget> Controller::createSignaturesEdit() { | ||||||
| 	Expects(_wrap != nullptr); | 	Expects(_wrap != nullptr); | ||||||
| 
 | 
 | ||||||
| 	if (!_channel->canEditInformation() | 	if (!_channel->canEditSignatures() | ||||||
| 		|| _channel->isMegagroup()) { | 		|| _channel->isMegagroup()) { | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
|  | @ -768,7 +863,7 @@ object_ptr<Ui::RpWidget> Controller::createSignaturesEdit() { | ||||||
| object_ptr<Ui::RpWidget> Controller::createInvitesEdit() { | object_ptr<Ui::RpWidget> Controller::createInvitesEdit() { | ||||||
| 	Expects(_wrap != nullptr); | 	Expects(_wrap != nullptr); | ||||||
| 
 | 
 | ||||||
| 	if (!_channel->canEditInformation() | 	if (!_channel->canEditInvites() | ||||||
| 		|| !_channel->isMegagroup()) { | 		|| !_channel->isMegagroup()) { | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
|  | @ -866,6 +961,7 @@ base::optional<Controller::Saving> Controller::validate() const { | ||||||
| 	if (validateUsername(result) | 	if (validateUsername(result) | ||||||
| 		&& validateTitle(result) | 		&& validateTitle(result) | ||||||
| 		&& validateDescription(result) | 		&& validateDescription(result) | ||||||
|  | 		&& validateHistoryVisibility(result) | ||||||
| 		&& validateInvites(result) | 		&& validateInvites(result) | ||||||
| 		&& validateSignatures(result)) { | 		&& validateSignatures(result)) { | ||||||
| 		return result; | 		return result; | ||||||
|  | @ -912,6 +1008,16 @@ bool Controller::validateDescription(Saving &to) const { | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool Controller::validateHistoryVisibility(Saving &to) const { | ||||||
|  | 	if (!_controls.historyVisibility | ||||||
|  | 		|| (_controls.privacy && _controls.privacy->value() == Privacy::Public)) { | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 	to.hiddenPreHistory | ||||||
|  | 		= (_controls.historyVisibility->value() == HistoryVisibility::Hidden); | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool Controller::validateInvites(Saving &to) const { | bool Controller::validateInvites(Saving &to) const { | ||||||
| 	if (!_controls.invites) { | 	if (!_controls.invites) { | ||||||
| 		return true; | 		return true; | ||||||
|  | @ -940,6 +1046,7 @@ void Controller::save() { | ||||||
| 		pushSaveStage([this] { saveUsername(); }); | 		pushSaveStage([this] { saveUsername(); }); | ||||||
| 		pushSaveStage([this] { saveTitle(); }); | 		pushSaveStage([this] { saveTitle(); }); | ||||||
| 		pushSaveStage([this] { saveDescription(); }); | 		pushSaveStage([this] { saveDescription(); }); | ||||||
|  | 		pushSaveStage([this] { saveHistoryVisibility(); }); | ||||||
| 		pushSaveStage([this] { saveInvites(); }); | 		pushSaveStage([this] { saveInvites(); }); | ||||||
| 		pushSaveStage([this] { saveSignatures(); }); | 		pushSaveStage([this] { saveSignatures(); }); | ||||||
| 		pushSaveStage([this] { savePhoto(); }); | 		pushSaveStage([this] { savePhoto(); }); | ||||||
|  | @ -1054,6 +1161,31 @@ void Controller::saveDescription() { | ||||||
| 	}).send(); | 	}).send(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Controller::saveHistoryVisibility() { | ||||||
|  | 	if (!_savingData.hiddenPreHistory | ||||||
|  | 		|| *_savingData.hiddenPreHistory == _channel->hiddenPreHistory()) { | ||||||
|  | 		return continueSave(); | ||||||
|  | 	} | ||||||
|  | 	request(MTPchannels_TogglePreHistoryHidden( | ||||||
|  | 		_channel->inputChannel, | ||||||
|  | 		MTP_bool(*_savingData.hiddenPreHistory) | ||||||
|  | 	)).done([this](const MTPUpdates &result) { | ||||||
|  | 		// Update in the result doesn't contain the
 | ||||||
|  | 		// channelFull:flags field which holds this value.
 | ||||||
|  | 		// So after saving we need to update it manually.
 | ||||||
|  | 		_channel->updateFullForced(); | ||||||
|  | 
 | ||||||
|  | 		Auth().api().applyUpdates(result); | ||||||
|  | 		continueSave(); | ||||||
|  | 	}).fail([this](const RPCError &error) { | ||||||
|  | 		if (error.type() == qstr("CHAT_NOT_MODIFIED")) { | ||||||
|  | 			continueSave(); | ||||||
|  | 		} else { | ||||||
|  | 			cancelSave(); | ||||||
|  | 		} | ||||||
|  | 	}).send(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Controller::saveInvites() { | void Controller::saveInvites() { | ||||||
| 	if (!_savingData.everyoneInvites | 	if (!_savingData.everyoneInvites | ||||||
| 		|| *_savingData.everyoneInvites == _channel->anyoneCanAddMembers()) { | 		|| *_savingData.everyoneInvites == _channel->anyoneCanAddMembers()) { | ||||||
|  |  | ||||||
|  | @ -983,6 +983,10 @@ bool ChannelData::anyoneCanAddMembers() const { | ||||||
| 	return (flags() & MTPDchannel::Flag::f_democracy); | 	return (flags() & MTPDchannel::Flag::f_democracy); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool ChannelData::hiddenPreHistory() const { | ||||||
|  | 	return (fullFlags() & MTPDchannelFull::Flag::f_hidden_prehistory); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool ChannelData::canAddMembers() const { | bool ChannelData::canAddMembers() const { | ||||||
| 	return (adminRights() & AdminRight::f_invite_users) | 	return (adminRights() & AdminRight::f_invite_users) | ||||||
| 		|| amCreator() | 		|| amCreator() | ||||||
|  | @ -1036,6 +1040,18 @@ bool ChannelData::canEditInformation() const { | ||||||
| 		|| amCreator(); | 		|| amCreator(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool ChannelData::canEditInvites() const { | ||||||
|  | 	return canEditInformation(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool ChannelData::canEditSignatures() const { | ||||||
|  | 	return canEditInformation(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool ChannelData::canEditPreHistoryHidden() const { | ||||||
|  | 	return canEditInformation(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool ChannelData::canEditUsername() const { | bool ChannelData::canEditUsername() const { | ||||||
| 	return amCreator() | 	return amCreator() | ||||||
| 		&& (fullFlags() | 		&& (fullFlags() | ||||||
|  |  | ||||||
|  | @ -971,6 +971,7 @@ public: | ||||||
| 	bool canEditMessages() const; | 	bool canEditMessages() const; | ||||||
| 	bool canDeleteMessages() const; | 	bool canDeleteMessages() const; | ||||||
| 	bool anyoneCanAddMembers() const; | 	bool anyoneCanAddMembers() const; | ||||||
|  | 	bool hiddenPreHistory() const; | ||||||
| 	bool canAddMembers() const; | 	bool canAddMembers() const; | ||||||
| 	bool canAddAdmins() const; | 	bool canAddAdmins() const; | ||||||
| 	bool canPinMessages() const; | 	bool canPinMessages() const; | ||||||
|  | @ -980,6 +981,9 @@ public: | ||||||
| 	bool canViewAdmins() const; | 	bool canViewAdmins() const; | ||||||
| 	bool canViewBanned() const; | 	bool canViewBanned() const; | ||||||
| 	bool canEditInformation() const; | 	bool canEditInformation() const; | ||||||
|  | 	bool canEditInvites() const; | ||||||
|  | 	bool canEditSignatures() const; | ||||||
|  | 	bool canEditPreHistoryHidden() const; | ||||||
| 	bool canEditUsername() const; | 	bool canEditUsername() const; | ||||||
| 	bool canEditStickers() const; | 	bool canEditStickers() const; | ||||||
| 	bool canDelete() const; | 	bool canDelete() const; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue