mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/telegramdesktop/tdesktop
synced 2026-09-20 08:03:45 +08:00
Added members grouping by role to participants controller.
This commit is contained in:
@@ -1034,33 +1034,37 @@ void ParticipantsOnlineSorter::sort() {
|
|||||||
_onlineCount = 0;
|
_onlineCount = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto now = base::unixtime::now();
|
if (_sortingEnabled) {
|
||||||
_delegate->peerListSortRows([&](
|
const auto now = base::unixtime::now();
|
||||||
const PeerListRow &a,
|
_delegate->peerListSortRows([&](
|
||||||
const PeerListRow &b) {
|
const PeerListRow &a,
|
||||||
return Data::SortByOnlineValue(a.peer()->asUser(), now) >
|
const PeerListRow &b) {
|
||||||
Data::SortByOnlineValue(b.peer()->asUser(), now);
|
return Data::SortByOnlineValue(a.peer()->asUser(), now) >
|
||||||
});
|
Data::SortByOnlineValue(b.peer()->asUser(), now);
|
||||||
|
});
|
||||||
|
}
|
||||||
refreshOnlineCount();
|
refreshOnlineCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ParticipantsOnlineSorter::setSortingEnabled(bool enabled) {
|
||||||
|
_sortingEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
rpl::producer<int> ParticipantsOnlineSorter::onlineCountValue() const {
|
rpl::producer<int> ParticipantsOnlineSorter::onlineCountValue() const {
|
||||||
return _onlineCount.value();
|
return _onlineCount.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticipantsOnlineSorter::refreshOnlineCount() {
|
void ParticipantsOnlineSorter::refreshOnlineCount() {
|
||||||
const auto now = base::unixtime::now();
|
const auto now = base::unixtime::now();
|
||||||
auto left = 0, right = _delegate->peerListFullRowsCount();
|
auto count = 0;
|
||||||
while (right > left) {
|
const auto rows = _delegate->peerListFullRowsCount();
|
||||||
const auto middle = (left + right) / 2;
|
for (auto i = 0; i != rows; ++i) {
|
||||||
const auto row = _delegate->peerListRowAt(middle);
|
const auto user = _delegate->peerListRowAt(i)->peer()->asUser();
|
||||||
if (Data::OnlineTextActive(row->peer()->asUser(), now)) {
|
if (user && Data::OnlineTextActive(user, now)) {
|
||||||
left = middle + 1;
|
++count;
|
||||||
} else {
|
|
||||||
right = middle;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_onlineCount = left;
|
_onlineCount = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParticipantsBoxController::SavedState::SavedState(
|
ParticipantsBoxController::SavedState::SavedState(
|
||||||
@@ -1112,6 +1116,20 @@ void ParticipantsBoxController::setupListChangeViewers() {
|
|||||||
channel->owner().megagroupParticipantAdded(
|
channel->owner().megagroupParticipantAdded(
|
||||||
channel
|
channel
|
||||||
) | rpl::on_next([=](not_null<UserData*> user) {
|
) | rpl::on_next([=](not_null<UserData*> user) {
|
||||||
|
if (_groupByRole.current()) {
|
||||||
|
if (!delegate()->peerListFindRow(user->id.value)) {
|
||||||
|
if (auto row = createRow(user)) {
|
||||||
|
const auto raw = row.get();
|
||||||
|
delegate()->peerListPrependRow(std::move(row));
|
||||||
|
if (_stories) {
|
||||||
|
_stories->process(raw);
|
||||||
|
}
|
||||||
|
refreshRows();
|
||||||
|
resort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (delegate()->peerListFullRowsCount() > 0) {
|
if (delegate()->peerListFullRowsCount() > 0) {
|
||||||
if (delegate()->peerListRowAt(0)->peer() == user) {
|
if (delegate()->peerListRowAt(0)->peer() == user) {
|
||||||
return;
|
return;
|
||||||
@@ -1128,9 +1146,7 @@ void ParticipantsBoxController::setupListChangeViewers() {
|
|||||||
_stories->process(raw);
|
_stories->process(raw);
|
||||||
}
|
}
|
||||||
refreshRows();
|
refreshRows();
|
||||||
if (_onlineSorter) {
|
resort();
|
||||||
_onlineSorter->sort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
@@ -1401,9 +1417,7 @@ void ParticipantsBoxController::restoreState(
|
|||||||
refreshRows();
|
refreshRows();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_onlineSorter) {
|
resort();
|
||||||
_onlineSorter->sort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1501,6 +1515,9 @@ void ParticipantsBoxController::prepare() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
recomputeTypeFor(user);
|
recomputeTypeFor(user);
|
||||||
|
if (_groupByRole.current()) {
|
||||||
|
resort();
|
||||||
|
}
|
||||||
refreshRows();
|
refreshRows();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
@@ -1618,7 +1635,7 @@ void ParticipantsBoxController::rebuildChatParticipants(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_onlineSorter->sort();
|
resort();
|
||||||
|
|
||||||
refreshRows();
|
refreshRows();
|
||||||
chatListReady();
|
chatListReady();
|
||||||
@@ -1777,9 +1794,7 @@ void ParticipantsBoxController::loadMoreRows() {
|
|||||||
|| (firstLoad && delegate()->peerListFullRowsCount() > 0)) {
|
|| (firstLoad && delegate()->peerListFullRowsCount() > 0)) {
|
||||||
refreshDescription();
|
refreshDescription();
|
||||||
}
|
}
|
||||||
if (_onlineSorter) {
|
resort();
|
||||||
_onlineSorter->sort();
|
|
||||||
}
|
|
||||||
refreshRows();
|
refreshRows();
|
||||||
}).fail([this] {
|
}).fail([this] {
|
||||||
_loadRequestId = 0;
|
_loadRequestId = 0;
|
||||||
@@ -1839,9 +1854,7 @@ bool ParticipantsBoxController::feedMegagroupLastParticipants() {
|
|||||||
//
|
//
|
||||||
//++_offset;
|
//++_offset;
|
||||||
}
|
}
|
||||||
if (_onlineSorter) {
|
resort();
|
||||||
_onlineSorter->sort();
|
|
||||||
}
|
|
||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2644,6 +2657,87 @@ void ParticipantsBoxController::refreshRows() {
|
|||||||
delegate()->peerListRefreshRows();
|
delegate()->peerListRefreshRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ParticipantsBoxController::memberRoleTier(
|
||||||
|
not_null<PeerData*> peer) const {
|
||||||
|
const auto user = peer->asUser();
|
||||||
|
if (user && _additional.isCreator(user)) {
|
||||||
|
return 0;
|
||||||
|
} else if (user && user->isBot()) {
|
||||||
|
return 2;
|
||||||
|
} else if (user && _additional.adminRights(user).has_value()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticipantsBoxController::sortByRoleAndName() {
|
||||||
|
delegate()->peerListSortRows([&](
|
||||||
|
const PeerListRow &a,
|
||||||
|
const PeerListRow &b) {
|
||||||
|
const auto tierA = memberRoleTier(a.peer());
|
||||||
|
const auto tierB = memberRoleTier(b.peer());
|
||||||
|
return (tierA != tierB)
|
||||||
|
? (tierA < tierB)
|
||||||
|
: (a.peer()->name().compare(
|
||||||
|
b.peer()->name(),
|
||||||
|
Qt::CaseInsensitive) < 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticipantsBoxController::applyRoleSectionHeaders() {
|
||||||
|
const auto count = delegate()->peerListFullRowsCount();
|
||||||
|
for (auto i = 0; i != count; ++i) {
|
||||||
|
const auto row = delegate()->peerListRowAt(i);
|
||||||
|
row->setSection([&] {
|
||||||
|
switch (memberRoleTier(row->peer())) {
|
||||||
|
case 0: return tr::lng_channel_admin_status_creator(tr::now);
|
||||||
|
case 1: return tr::lng_channel_admins(tr::now);
|
||||||
|
case 2: return tr::lng_filters_type_bots(tr::now);
|
||||||
|
}
|
||||||
|
return tr::lng_profile_participants_section(tr::now);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticipantsBoxController::resort() {
|
||||||
|
if (_groupByRole.current()) {
|
||||||
|
if (_onlineSorter) {
|
||||||
|
_onlineSorter->setSortingEnabled(false);
|
||||||
|
_onlineSorter->sort();
|
||||||
|
}
|
||||||
|
sortByRoleAndName();
|
||||||
|
applyRoleSectionHeaders();
|
||||||
|
delegate()->peerListSetShowSectionHeaders(true);
|
||||||
|
delegate()->peerListRefreshRows();
|
||||||
|
} else {
|
||||||
|
delegate()->peerListSetShowSectionHeaders(false);
|
||||||
|
if (_onlineSorter) {
|
||||||
|
_onlineSorter->setSortingEnabled(true);
|
||||||
|
_onlineSorter->sort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticipantsBoxController::setGroupByRole(bool grouped) {
|
||||||
|
if (_groupByRole.current() == grouped) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_groupByRole = grouped;
|
||||||
|
resort();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> ParticipantsBoxController::groupByRoleValue() const {
|
||||||
|
return _groupByRole.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ParticipantsBoxController::groupByRoleAvailableValue() const
|
||||||
|
-> rpl::producer<bool> {
|
||||||
|
if (_peer->isMegagroup()) {
|
||||||
|
return Info::Profile::CanViewParticipantsValue(_peer->asMegagroup());
|
||||||
|
}
|
||||||
|
return rpl::single(true);
|
||||||
|
}
|
||||||
|
|
||||||
ParticipantsBoxSearchController::ParticipantsBoxSearchController(
|
ParticipantsBoxSearchController::ParticipantsBoxSearchController(
|
||||||
not_null<ChannelData*> channel,
|
not_null<ChannelData*> channel,
|
||||||
Role role,
|
Role role,
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ public:
|
|||||||
not_null<PeerListDelegate*> delegate);
|
not_null<PeerListDelegate*> delegate);
|
||||||
|
|
||||||
void sort();
|
void sort();
|
||||||
|
void setSortingEnabled(bool enabled);
|
||||||
rpl::producer<int> onlineCountValue() const;
|
rpl::producer<int> onlineCountValue() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -97,6 +98,7 @@ private:
|
|||||||
const not_null<PeerListDelegate*> _delegate;
|
const not_null<PeerListDelegate*> _delegate;
|
||||||
base::Timer _sortByOnlineTimer;
|
base::Timer _sortByOnlineTimer;
|
||||||
rpl::variable<int> _onlineCount = 0;
|
rpl::variable<int> _onlineCount = 0;
|
||||||
|
bool _sortingEnabled = true;
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -228,6 +230,10 @@ public:
|
|||||||
[[nodiscard]] rpl::producer<int> onlineCountValue() const;
|
[[nodiscard]] rpl::producer<int> onlineCountValue() const;
|
||||||
[[nodiscard]] rpl::producer<int> fullCountValue() const;
|
[[nodiscard]] rpl::producer<int> fullCountValue() const;
|
||||||
|
|
||||||
|
void setGroupByRole(bool grouped);
|
||||||
|
[[nodiscard]] rpl::producer<bool> groupByRoleValue() const;
|
||||||
|
[[nodiscard]] rpl::producer<bool> groupByRoleAvailableValue() const;
|
||||||
|
|
||||||
void setStoriesShown(bool shown);
|
void setStoriesShown(bool shown);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -314,6 +320,10 @@ private:
|
|||||||
void subscribeToCreatorChange(not_null<ChannelData*> channel);
|
void subscribeToCreatorChange(not_null<ChannelData*> channel);
|
||||||
void fullListRefresh();
|
void fullListRefresh();
|
||||||
void refreshRows();
|
void refreshRows();
|
||||||
|
void resort();
|
||||||
|
void sortByRoleAndName();
|
||||||
|
void applyRoleSectionHeaders();
|
||||||
|
[[nodiscard]] int memberRoleTier(not_null<PeerData*> peer) const;
|
||||||
|
|
||||||
// It may be nullptr in subclasses of this controller.
|
// It may be nullptr in subclasses of this controller.
|
||||||
Window::SessionNavigation *_navigation = nullptr;
|
Window::SessionNavigation *_navigation = nullptr;
|
||||||
@@ -326,6 +336,7 @@ private:
|
|||||||
bool _allLoaded = false;
|
bool _allLoaded = false;
|
||||||
ParticipantsAdditionalData _additional;
|
ParticipantsAdditionalData _additional;
|
||||||
std::unique_ptr<ParticipantsOnlineSorter> _onlineSorter;
|
std::unique_ptr<ParticipantsOnlineSorter> _onlineSorter;
|
||||||
|
rpl::variable<bool> _groupByRole = false;
|
||||||
rpl::variable<int> _onlineCountValue;
|
rpl::variable<int> _onlineCountValue;
|
||||||
rpl::variable<int> _fullCountValue;
|
rpl::variable<int> _fullCountValue;
|
||||||
Ui::BoxPointer _editBox;
|
Ui::BoxPointer _editBox;
|
||||||
|
|||||||
Reference in New Issue
Block a user