diff --git a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp index 25853e0f85..ab05d9bccb 100644 --- a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp @@ -1522,6 +1522,7 @@ void AddSpecialBoxController::editAdminDone( } _additional.applyAdminLocally(user, rights, rank); + // _adminDoneCallback should call changes().chatAdminUpdated. if (const auto callback = _adminDoneCallback) { callback(user, rights, rank); } diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp index e168e800e0..ea60f38333 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp @@ -461,6 +461,7 @@ void ParticipantsAdditionalData::setExternal( _adminRights.erase(user); _adminCanEdit.erase(user); _adminPromotedBy.erase(user); + _adminRanks.erase(user); _admins.erase(user); } _restrictedRights.erase(participant); @@ -538,6 +539,7 @@ void ParticipantsAdditionalData::fillFromChannel( _adminRights.erase(user); _adminCanEdit.erase(user); _adminPromotedBy.erase(user); + _adminRanks.erase(user); _restrictedRights.emplace(user, restricted->second.rights); } } @@ -743,6 +745,7 @@ UserData *ParticipantsAdditionalData::applyRegular(UserId userId) { _adminRights.erase(user); _adminCanEdit.erase(user); _adminPromotedBy.erase(user); + _adminRanks.erase(user); _restrictedRights.erase(user); _kicked.erase(user); _restrictedBy.erase(user); @@ -761,6 +764,7 @@ PeerData *ParticipantsAdditionalData::applyBanned( _adminRights.erase(user); _adminCanEdit.erase(user); _adminPromotedBy.erase(user); + _adminRanks.erase(user); } if (data.isKicked()) { _kicked.emplace(participant); @@ -1270,6 +1274,33 @@ void ParticipantsBoxController::prepare() { } else { rebuild(); } + + _peer->session().changes().chatAdminChanges( + ) | rpl::start_with_next([=](const Data::ChatAdminChange &update) { + if (update.peer != _peer) { + return; + } + const auto user = update.user; + const auto rights = ChatAdminRightsInfo(update.rights); + const auto rank = update.rank; + _additional.applyAdminLocally(user, rights, rank); + if (!_additional.isCreator(user) || !user->isSelf()) { + if (!rights.flags) { + if (_role == Role::Admins) { + removeRow(user); + } + } else { + if (_role == Role::Admins) { + prependRow(user); + } else if (_role == Role::Kicked + || _role == Role::Restricted) { + removeRow(user); + } + } + } + recomputeTypeFor(user); + refreshRows(); + }, lifetime()); } void ParticipantsBoxController::unload() { @@ -1800,23 +1831,8 @@ void ParticipantsBoxController::editAdminDone( if (_editParticipantBox) { _editParticipantBox->closeBox(); } - - _additional.applyAdminLocally(user, rights, rank); - if (!_additional.isCreator(user) || !user->isSelf()) { - if (!rights.flags) { - if (_role == Role::Admins) { - removeRow(user); - } - } else { - if (_role == Role::Admins) { - prependRow(user); - } else if (_role == Role::Kicked || _role == Role::Restricted) { - removeRow(user); - } - } - } - recomputeTypeFor(user); - refreshRows(); + const auto flags = rights.flags; + user->session().changes().chatAdminChanged(_peer, user, flags, rank); } void ParticipantsBoxController::showRestricted(not_null user) { diff --git a/Telegram/SourceFiles/data/data_changes.cpp b/Telegram/SourceFiles/data/data_changes.cpp index 6f2a554da9..5356d48065 100644 --- a/Telegram/SourceFiles/data/data_changes.cpp +++ b/Telegram/SourceFiles/data/data_changes.cpp @@ -340,6 +340,23 @@ rpl::producer Changes::realtimeStoryUpdates( return _storyChanges.realtimeUpdates(flag); } +void Changes::chatAdminChanged( + not_null peer, + not_null user, + ChatAdminRights rights, + QString rank) { + _chatAdminChanges.fire({ + .peer = peer, + .user = user, + .rights = rights, + .rank = std::move(rank), + }); +} + +rpl::producer Changes::chatAdminChanges() const { + return _chatAdminChanges.events(); +} + void Changes::scheduleNotifications() { if (!_notify) { _notify = true; diff --git a/Telegram/SourceFiles/data/data_changes.h b/Telegram/SourceFiles/data/data_changes.h index f3215d2599..190f3f554c 100644 --- a/Telegram/SourceFiles/data/data_changes.h +++ b/Telegram/SourceFiles/data/data_changes.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "base/flags.h" +#include "data/data_chat_participant_status.h" class History; class PeerData; @@ -271,6 +272,13 @@ struct StoryUpdate { }; +struct ChatAdminChange { + not_null peer; + not_null user; + ChatAdminRights rights; + QString rank; +}; + class Changes final { public: explicit Changes(not_null session); @@ -383,6 +391,13 @@ public: [[nodiscard]] rpl::producer realtimeStoryUpdates( StoryUpdate::Flag flag) const; + void chatAdminChanged( + not_null peer, + not_null user, + ChatAdminRights rights, + QString rank); + [[nodiscard]] rpl::producer chatAdminChanges() const; + void sendNotifications(); private: @@ -435,6 +450,7 @@ private: Manager _messageChanges; Manager _entryChanges; Manager _storyChanges; + rpl::event_stream _chatAdminChanges; bool _notify = false; diff --git a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp index 1987be5d49..619a5206a8 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp @@ -39,6 +39,10 @@ void MemberListRow::setType(Type type) { : QString()); } +MemberListRow::Type MemberListRow::type() const { + return _type; +} + bool MemberListRow::rightActionDisabled() const { return true; } diff --git a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.h b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.h index 37d04cb7c6..c867d731d5 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.h +++ b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.h @@ -34,6 +34,7 @@ public: MemberListRow(not_null user, Type type); void setType(Type type); + [[nodiscard]] Type type() const; bool rightActionDisabled() const override; QMargins rightActionMargins() const override; void refreshStatus() override;