Edit pre-history visibility in megagroups.

This commit is contained in:
John Preston 2017-11-22 12:04:45 +04:00
parent 2387b66e86
commit 542ba89f25
5 changed files with 167 additions and 12 deletions

View File

@ -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";

View File

@ -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;

View File

@ -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),
st::editPeerInviteLinkMargins);
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, _wrap,
lang(lng_group_invite_create), lang(lng_group_invite_create),
st::editPeerInviteLinkButton), st::editPeerInviteLinkButton)
st::editPeerInviteLinkMargins); )->addClickHandler([this] {
result->entity()->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()) {

View File

@ -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()

View File

@ -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;