diff --git a/Telegram/SourceFiles/boxes/peer_list_box.h b/Telegram/SourceFiles/boxes/peer_list_box.h index 81dd5a076..05df4bf74 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.h +++ b/Telegram/SourceFiles/boxes/peer_list_box.h @@ -399,6 +399,7 @@ public: callback(searchEntity.second.begin(), searchEntity.second.end()); } refreshIndices(); + update(); } rpl::producer scrollToRequests() const { diff --git a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp index 3aca0f4fa..b41db54d0 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp @@ -61,11 +61,20 @@ void ChatMembersController::prepare() { if (!delegate()->peerListFullRowsCount()) { Auth().api().requestFullPeer(_chat); } + using UpdateFlag = Notify::PeerUpdate::Flag; subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler( - Notify::PeerUpdate::Flag::MembersChanged, + UpdateFlag::MembersChanged | UpdateFlag::UserOnlineChanged, [this](const Notify::PeerUpdate &update) { - if (update.peer == _chat) { - rebuildRows(); + if (update.flags & UpdateFlag::MembersChanged) { + if (update.peer == _chat) { + rebuildRows(); + } + } else if (update.flags & UpdateFlag::UserOnlineChanged) { + auto now = unixtime(); + delegate()->peerListSortRows([now](const PeerListRow &a, const PeerListRow &b) { + return App::onlineForSort(a.peer()->asUser(), now) > + App::onlineForSort(b.peer()->asUser(), now); + }); } })); } diff --git a/Telegram/SourceFiles/profile/profile_channel_controllers.cpp b/Telegram/SourceFiles/profile/profile_channel_controllers.cpp index 614478556..6ab0d64a1 100644 --- a/Telegram/SourceFiles/profile/profile_channel_controllers.cpp +++ b/Telegram/SourceFiles/profile/profile_channel_controllers.cpp @@ -28,6 +28,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "apiwrap.h" #include "lang/lang_keys.h" #include "mainwidget.h" +#include "observer_peer.h" #include "dialogs/dialogs_indexed_list.h" namespace Profile { @@ -35,16 +36,56 @@ namespace { constexpr auto kParticipantsFirstPageCount = 16; constexpr auto kParticipantsPerPage = 200; +constexpr auto kSortByOnlineDelay = TimeMs(1000); } // namespace -ParticipantsBoxController::ParticipantsBoxController(not_null channel, Role role) +ParticipantsBoxController::ParticipantsBoxController( + not_null channel, + Role role) : PeerListController(CreateSearchController(channel, role, &_additional)) , _channel(channel) , _role(role) { if (_channel->mgInfo) { _additional.creator = _channel->mgInfo->creator; } + if (_role == Role::Profile) { + setupSortByOnline(); + } +} + +void ParticipantsBoxController::setupSortByOnline() { + _sortByOnlineTimer.setCallback([this] { sortByOnline(); }); + using UpdateFlag = Notify::PeerUpdate::Flag; + subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler( + UpdateFlag::UserOnlineChanged, + [this](const Notify::PeerUpdate &update) { + if (auto row = delegate()->peerListFindRow( + update.peer->id)) { + row->refreshStatus(); + sortByOnlineDelayed(); + } + })); +} + +void ParticipantsBoxController::sortByOnlineDelayed() { + if (!_sortByOnlineTimer.isActive()) { + _sortByOnlineTimer.callOnce(kSortByOnlineDelay); + } +} + +void ParticipantsBoxController::sortByOnline() { + if (_role != Role::Profile + || _channel->membersCount() > Global::ChatSizeMax()) { + return; + } + auto now = unixtime(); + delegate()->peerListSortRows([now]( + const PeerListRow &a, + const PeerListRow &b) { + return App::onlineForSort(a.peer()->asUser(), now) > + App::onlineForSort(b.peer()->asUser(), now); + }); } std::unique_ptr @@ -278,6 +319,7 @@ void ParticipantsBoxController::loadMoreRows() { }); } } + sortByOnline(); delegate()->peerListRefreshRows(); }).fail([this](const RPCError &error) { _loadRequestId = 0; @@ -327,6 +369,7 @@ bool ParticipantsBoxController::feedMegagroupLastParticipants() { appendRow(user); ++_offset; } + sortByOnline(); return true; } diff --git a/Telegram/SourceFiles/profile/profile_channel_controllers.h b/Telegram/SourceFiles/profile/profile_channel_controllers.h index a05b68043..393024aba 100644 --- a/Telegram/SourceFiles/profile/profile_channel_controllers.h +++ b/Telegram/SourceFiles/profile/profile_channel_controllers.h @@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "boxes/peer_list_box.h" #include "mtproto/sender.h" +#include "base/timer.h" #include "base/weak_unique_ptr.h" namespace Profile { @@ -76,6 +77,9 @@ protected: private: static std::unique_ptr CreateSearchController(not_null channel, Role role, not_null additional); + void setupSortByOnline(); + void sortByOnlineDelayed(); + void sortByOnline(); void showAdmin(not_null user); void editAdminDone(not_null user, const MTPChannelAdminRights &rights); void showRestricted(not_null user); @@ -98,6 +102,8 @@ private: QPointer _editBox; QPointer _addBox; + base::Timer _sortByOnlineTimer; + }; // Members, banned and restricted users server side search.