From 542ba89f256b0ffed483833037075261145296fb Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 22 Nov 2017 12:04:45 +0400 Subject: [PATCH] Edit pre-history visibility in megagroups. --- Telegram/Resources/langs/lang.strings | 5 + Telegram/SourceFiles/apiwrap.cpp | 6 +- .../boxes/peers/edit_peer_info_box.cpp | 148 +++++++++++++++++- Telegram/SourceFiles/data/data_peer.cpp | 16 ++ Telegram/SourceFiles/data/data_peer.h | 4 + 5 files changed, 167 insertions(+), 12 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index b37d0c0d88..e50e06af77 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -668,6 +668,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_manage_peer_administrators" = "Administrators"; "lng_manage_peer_banned_users" = "Banned 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_group_title" = "Report group"; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index ae248a815d..11a4a33cb0 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -736,13 +736,11 @@ void ApiWrap::applyLastParticipantsList( if (!keyboardBotFound) { h->clearLastKeyboard(); } - int newMembersCount = qMax(fullCount, list.size()); - if (newMembersCount > peer->membersCount()) { - peer->setMembersCount(newMembersCount); - } if (!bots) { if (list.isEmpty()) { peer->setMembersCount(peer->mgInfo->lastParticipants.size()); + } else { + peer->setMembersCount(fullCount); } Notify::PeerUpdate update(peer); update.flags |= Notify::PeerUpdate::Flag::MembersChanged | Notify::PeerUpdate::Flag::AdminsChanged; diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 91c602a9fc..27af118914 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -69,6 +69,10 @@ private: Everyone, OnlyAdmins, }; + enum class HistoryVisibility { + Visible, + Hidden, + }; enum class UsernameState { Normal, TooMany, @@ -90,6 +94,9 @@ private: Ui::SlideWrap *editInviteLinkWrap = nullptr; Ui::FlatLabel *inviteLink = nullptr; + std::shared_ptr> historyVisibility; + Ui::SlideWrap *historyVisibilityWrap = nullptr; + std::shared_ptr> invites; Ui::Checkbox *signatures = nullptr; }; @@ -97,6 +104,7 @@ private: base::optional username; base::optional title; base::optional description; + base::optional hiddenPreHistory; base::optional signatures; base::optional everyoneInvites; }; @@ -110,6 +118,7 @@ private: object_ptr createUsernameEdit(); object_ptr createInviteLinkCreate(); object_ptr createInviteLinkEdit(); + object_ptr createHistoryVisibilityEdit(); object_ptr createSignaturesEdit(); object_ptr createInvitesEdit(); object_ptr createDeleteButton(); @@ -132,6 +141,7 @@ private: bool inviteLinkShown() const; void refreshEditInviteLink(); void refreshCreateInviteLink(); + void refreshHistoryVisibility(); void createInviteLink(); void revokeInviteLink(); void exportInviteLink(const QString &confirmation); @@ -140,6 +150,7 @@ private: bool validateUsername(Saving &to) const; bool validateTitle(Saving &to) const; bool validateDescription(Saving &to) const; + bool validateHistoryVisibility(Saving &to) const; bool validateInvites(Saving &to) const; bool validateSignatures(Saving &to) const; @@ -147,6 +158,7 @@ private: void saveUsername(); void saveTitle(); void saveDescription(); + void saveHistoryVisibility(); void saveInvites(); void saveSignatures(); void savePhoto(); @@ -202,6 +214,7 @@ object_ptr Controller::createContent() { _wrap->add(createPrivaciesEdit()); _wrap->add(createInviteLinkCreate()); _wrap->add(createInviteLinkEdit()); + _wrap->add(createHistoryVisibilityEdit()); _wrap->add(createSignaturesEdit()); _wrap->add(createInvitesEdit()); _wrap->add(createDeleteButton()); @@ -435,6 +448,7 @@ void Controller::privacyChanged(Privacy value) { } refreshCreateInviteLink(); refreshEditInviteLink(); + refreshHistoryVisibility(); if (value == Privacy::Public) { _controls.usernameResult = nullptr; checkUsernameAvailability(); @@ -709,14 +723,25 @@ object_ptr Controller::createInviteLinkCreate() { return nullptr; } - auto result = object_ptr>( + auto result = object_ptr>( _wrap, - object_ptr( - _wrap, - lang(lng_group_invite_create), - st::editPeerInviteLinkButton), + object_ptr(_wrap), st::editPeerInviteLinkMargins); - result->entity()->addClickHandler([this] { + auto container = result->entity(); + + container->add(object_ptr( + container, + Lang::Viewer(lng_profile_invite_link_section), + st::editPeerSectionLabel)); + container->add(object_ptr( + container, + st::editPeerInviteLinkSkip)); + + container->add(object_ptr( + _wrap, + lang(lng_group_invite_create), + st::editPeerInviteLinkButton) + )->addClickHandler([this] { createInviteLink(); }); _controls.createInviteLinkWrap = result.data(); @@ -738,10 +763,80 @@ void Controller::refreshCreateInviteLink() { anim::type::instant); } +object_ptr Controller::createHistoryVisibilityEdit() { + Expects(_wrap != nullptr); + + if (!_channel->canEditPreHistoryHidden() + || !_channel->isMegagroup()) { + return nullptr; + } + auto result = object_ptr>( + _wrap, + object_ptr(_wrap), + st::editPeerInvitesMargins); + _controls.historyVisibilityWrap = result.data(); + auto container = result->entity(); + + _controls.historyVisibility + = std::make_shared>( + _channel->hiddenPreHistory() + ? HistoryVisibility::Hidden + : HistoryVisibility::Visible); + auto addButton = [&]( + HistoryVisibility value, + LangKey groupTextKey, + LangKey groupAboutKey) { + container->add(object_ptr( + container, + st::editPeerPrivacyTopSkip + st::editPeerPrivacyBottomSkip)); + container->add(object_ptr>( + container, + _controls.historyVisibility, + value, + lang(groupTextKey), + st::defaultBoxCheckbox)); + container->add(object_ptr>( + container, + object_ptr( + container, + Lang::Viewer(groupAboutKey), + st::editPeerPrivacyLabel), + st::editPeerPrivacyLabelMargins)); + }; + + container->add(object_ptr( + 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 Controller::createSignaturesEdit() { Expects(_wrap != nullptr); - if (!_channel->canEditInformation() + if (!_channel->canEditSignatures() || _channel->isMegagroup()) { return nullptr; } @@ -768,7 +863,7 @@ object_ptr Controller::createSignaturesEdit() { object_ptr Controller::createInvitesEdit() { Expects(_wrap != nullptr); - if (!_channel->canEditInformation() + if (!_channel->canEditInvites() || !_channel->isMegagroup()) { return nullptr; } @@ -866,6 +961,7 @@ base::optional Controller::validate() const { if (validateUsername(result) && validateTitle(result) && validateDescription(result) + && validateHistoryVisibility(result) && validateInvites(result) && validateSignatures(result)) { return result; @@ -912,6 +1008,16 @@ bool Controller::validateDescription(Saving &to) const { 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 { if (!_controls.invites) { return true; @@ -940,6 +1046,7 @@ void Controller::save() { pushSaveStage([this] { saveUsername(); }); pushSaveStage([this] { saveTitle(); }); pushSaveStage([this] { saveDescription(); }); + pushSaveStage([this] { saveHistoryVisibility(); }); pushSaveStage([this] { saveInvites(); }); pushSaveStage([this] { saveSignatures(); }); pushSaveStage([this] { savePhoto(); }); @@ -1054,6 +1161,31 @@ void Controller::saveDescription() { }).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() { if (!_savingData.everyoneInvites || *_savingData.everyoneInvites == _channel->anyoneCanAddMembers()) { diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 083d49d52c..4cde889b54 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -983,6 +983,10 @@ bool ChannelData::anyoneCanAddMembers() const { return (flags() & MTPDchannel::Flag::f_democracy); } +bool ChannelData::hiddenPreHistory() const { + return (fullFlags() & MTPDchannelFull::Flag::f_hidden_prehistory); +} + bool ChannelData::canAddMembers() const { return (adminRights() & AdminRight::f_invite_users) || amCreator() @@ -1036,6 +1040,18 @@ bool ChannelData::canEditInformation() const { || amCreator(); } +bool ChannelData::canEditInvites() const { + return canEditInformation(); +} + +bool ChannelData::canEditSignatures() const { + return canEditInformation(); +} + +bool ChannelData::canEditPreHistoryHidden() const { + return canEditInformation(); +} + bool ChannelData::canEditUsername() const { return amCreator() && (fullFlags() diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index db09cf5ce1..b78accf058 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -971,6 +971,7 @@ public: bool canEditMessages() const; bool canDeleteMessages() const; bool anyoneCanAddMembers() const; + bool hiddenPreHistory() const; bool canAddMembers() const; bool canAddAdmins() const; bool canPinMessages() const; @@ -980,6 +981,9 @@ public: bool canViewAdmins() const; bool canViewBanned() const; bool canEditInformation() const; + bool canEditInvites() const; + bool canEditSignatures() const; + bool canEditPreHistoryHidden() const; bool canEditUsername() const; bool canEditStickers() const; bool canDelete() const;