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;
|
||||
return;
|
||||
}
|
||||
const auto now = base::unixtime::now();
|
||||
_delegate->peerListSortRows([&](
|
||||
const PeerListRow &a,
|
||||
const PeerListRow &b) {
|
||||
return Data::SortByOnlineValue(a.peer()->asUser(), now) >
|
||||
Data::SortByOnlineValue(b.peer()->asUser(), now);
|
||||
});
|
||||
if (_sortingEnabled) {
|
||||
const auto now = base::unixtime::now();
|
||||
_delegate->peerListSortRows([&](
|
||||
const PeerListRow &a,
|
||||
const PeerListRow &b) {
|
||||
return Data::SortByOnlineValue(a.peer()->asUser(), now) >
|
||||
Data::SortByOnlineValue(b.peer()->asUser(), now);
|
||||
});
|
||||
}
|
||||
refreshOnlineCount();
|
||||
}
|
||||
|
||||
void ParticipantsOnlineSorter::setSortingEnabled(bool enabled) {
|
||||
_sortingEnabled = enabled;
|
||||
}
|
||||
|
||||
rpl::producer<int> ParticipantsOnlineSorter::onlineCountValue() const {
|
||||
return _onlineCount.value();
|
||||
}
|
||||
|
||||
void ParticipantsOnlineSorter::refreshOnlineCount() {
|
||||
const auto now = base::unixtime::now();
|
||||
auto left = 0, right = _delegate->peerListFullRowsCount();
|
||||
while (right > left) {
|
||||
const auto middle = (left + right) / 2;
|
||||
const auto row = _delegate->peerListRowAt(middle);
|
||||
if (Data::OnlineTextActive(row->peer()->asUser(), now)) {
|
||||
left = middle + 1;
|
||||
} else {
|
||||
right = middle;
|
||||
auto count = 0;
|
||||
const auto rows = _delegate->peerListFullRowsCount();
|
||||
for (auto i = 0; i != rows; ++i) {
|
||||
const auto user = _delegate->peerListRowAt(i)->peer()->asUser();
|
||||
if (user && Data::OnlineTextActive(user, now)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
_onlineCount = left;
|
||||
_onlineCount = count;
|
||||
}
|
||||
|
||||
ParticipantsBoxController::SavedState::SavedState(
|
||||
@@ -1112,6 +1116,20 @@ void ParticipantsBoxController::setupListChangeViewers() {
|
||||
channel->owner().megagroupParticipantAdded(
|
||||
channel
|
||||
) | 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()->peerListRowAt(0)->peer() == user) {
|
||||
return;
|
||||
@@ -1128,9 +1146,7 @@ void ParticipantsBoxController::setupListChangeViewers() {
|
||||
_stories->process(raw);
|
||||
}
|
||||
refreshRows();
|
||||
if (_onlineSorter) {
|
||||
_onlineSorter->sort();
|
||||
}
|
||||
resort();
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
@@ -1401,9 +1417,7 @@ void ParticipantsBoxController::restoreState(
|
||||
refreshRows();
|
||||
}
|
||||
}
|
||||
if (_onlineSorter) {
|
||||
_onlineSorter->sort();
|
||||
}
|
||||
resort();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1501,6 +1515,9 @@ void ParticipantsBoxController::prepare() {
|
||||
}
|
||||
}
|
||||
recomputeTypeFor(user);
|
||||
if (_groupByRole.current()) {
|
||||
resort();
|
||||
}
|
||||
refreshRows();
|
||||
}, lifetime());
|
||||
|
||||
@@ -1618,7 +1635,7 @@ void ParticipantsBoxController::rebuildChatParticipants(
|
||||
}
|
||||
}
|
||||
}
|
||||
_onlineSorter->sort();
|
||||
resort();
|
||||
|
||||
refreshRows();
|
||||
chatListReady();
|
||||
@@ -1777,9 +1794,7 @@ void ParticipantsBoxController::loadMoreRows() {
|
||||
|| (firstLoad && delegate()->peerListFullRowsCount() > 0)) {
|
||||
refreshDescription();
|
||||
}
|
||||
if (_onlineSorter) {
|
||||
_onlineSorter->sort();
|
||||
}
|
||||
resort();
|
||||
refreshRows();
|
||||
}).fail([this] {
|
||||
_loadRequestId = 0;
|
||||
@@ -1839,9 +1854,7 @@ bool ParticipantsBoxController::feedMegagroupLastParticipants() {
|
||||
//
|
||||
//++_offset;
|
||||
}
|
||||
if (_onlineSorter) {
|
||||
_onlineSorter->sort();
|
||||
}
|
||||
resort();
|
||||
return added;
|
||||
}
|
||||
|
||||
@@ -2644,6 +2657,87 @@ void ParticipantsBoxController::refreshRows() {
|
||||
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(
|
||||
not_null<ChannelData*> channel,
|
||||
Role role,
|
||||
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
not_null<PeerListDelegate*> delegate);
|
||||
|
||||
void sort();
|
||||
void setSortingEnabled(bool enabled);
|
||||
rpl::producer<int> onlineCountValue() const;
|
||||
|
||||
private:
|
||||
@@ -97,6 +98,7 @@ private:
|
||||
const not_null<PeerListDelegate*> _delegate;
|
||||
base::Timer _sortByOnlineTimer;
|
||||
rpl::variable<int> _onlineCount = 0;
|
||||
bool _sortingEnabled = true;
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
@@ -228,6 +230,10 @@ public:
|
||||
[[nodiscard]] rpl::producer<int> onlineCountValue() 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);
|
||||
|
||||
protected:
|
||||
@@ -314,6 +320,10 @@ private:
|
||||
void subscribeToCreatorChange(not_null<ChannelData*> channel);
|
||||
void fullListRefresh();
|
||||
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.
|
||||
Window::SessionNavigation *_navigation = nullptr;
|
||||
@@ -326,6 +336,7 @@ private:
|
||||
bool _allLoaded = false;
|
||||
ParticipantsAdditionalData _additional;
|
||||
std::unique_ptr<ParticipantsOnlineSorter> _onlineSorter;
|
||||
rpl::variable<bool> _groupByRole = false;
|
||||
rpl::variable<int> _onlineCountValue;
|
||||
rpl::variable<int> _fullCountValue;
|
||||
Ui::BoxPointer _editBox;
|
||||
|
||||
Reference in New Issue
Block a user