From 0684db9bd8a0cf4df28da4ff462b03cf99464d64 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 17 Mar 2021 20:37:29 +0400 Subject: [PATCH] Improve participants sorting in voice chats. --- Telegram/Resources/tl/api.tl | 4 +- .../SourceFiles/calls/calls_group_members.cpp | 41 +++++++++++++++---- Telegram/SourceFiles/data/data_group_call.cpp | 5 +++ Telegram/SourceFiles/data/data_group_call.h | 2 + Telegram/ThirdParty/tgcalls | 2 +- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/Telegram/Resources/tl/api.tl b/Telegram/Resources/tl/api.tl index eb7a11d947..7c4eb92723 100644 --- a/Telegram/Resources/tl/api.tl +++ b/Telegram/Resources/tl/api.tl @@ -1203,7 +1203,7 @@ peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked; stats.messageStats#8999f295 views_graph:StatsGraph = stats.MessageStats; groupCallDiscarded#7780bcb4 id:long access_hash:long duration:int = GroupCall; -groupCall#c0c2052e flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true id:long access_hash:long participants_count:int params:flags.0?DataJSON title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int version:int = GroupCall; +groupCall#c0c2052e flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true id:long access_hash:long participants_count:int params:flags.0?DataJSON title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int version:int = GroupCall; inputGroupCall#d8aa840f id:long access_hash:long = InputGroupCall; @@ -1572,7 +1572,7 @@ channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector = channels.deleteChannel#c0111fe3 channel:InputChannel = Updates; channels.exportMessageLink#e63fadeb flags:# grouped:flags.0?true thread:flags.1?true channel:InputChannel id:int = ExportedMessageLink; channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates; -channels.getAdminedPublicChannels#f8b036af flags:# by_location:flags.0?true check_limit:flags.1?true for_groupcall:flags.2?true = messages.Chats; +channels.getAdminedPublicChannels#f8b036af flags:# by_location:flags.0?true check_limit:flags.1?true = messages.Chats; channels.editBanned#72796912 channel:InputChannel user_id:InputUser banned_rights:ChatBannedRights = Updates; channels.getAdminLog#33ddf480 flags:# channel:InputChannel q:string events_filter:flags.0?ChannelAdminLogEventsFilter admins:flags.1?Vector max_id:long min_id:long limit:int = channels.AdminLogResults; channels.setStickers#ea8ca4f9 channel:InputChannel stickerset:InputStickerSet = Bool; diff --git a/Telegram/SourceFiles/calls/calls_group_members.cpp b/Telegram/SourceFiles/calls/calls_group_members.cpp index ac779deca4..170e4beea8 100644 --- a/Telegram/SourceFiles/calls/calls_group_members.cpp +++ b/Telegram/SourceFiles/calls/calls_group_members.cpp @@ -1024,34 +1024,41 @@ void MembersController::appendInvitedUsers() { void MembersController::updateRow( const std::optional &was, const Data::GroupCall::Participant &now) { - auto reorderIfInvitedBeforeIndex = 0; + auto reorderIfInvitedBefore = 0; + auto checkPosition = (Row*)nullptr; + auto addedToBottom = (Row*)nullptr; if (const auto row = findRow(now.peer)) { if (row->state() == Row::State::Invited) { - reorderIfInvitedBeforeIndex = row->absoluteIndex(); + reorderIfInvitedBefore = row->absoluteIndex(); } updateRow(row, &now); if ((now.speaking && (!was || !was->speaking)) || (now.raisedHandRating != (was ? was->raisedHandRating : 0)) || (!now.canSelfUnmute && was && was->canSelfUnmute)) { - checkRowPosition(row); + checkPosition = row; } } else if (auto row = createRow(now)) { if (row->speaking()) { delegate()->peerListPrependRow(std::move(row)); } else { - reorderIfInvitedBeforeIndex = delegate()->peerListFullRowsCount(); + reorderIfInvitedBefore = delegate()->peerListFullRowsCount(); + if (now.raisedHandRating != 0) { + checkPosition = row.get(); + } else { + addedToBottom = row.get(); + } delegate()->peerListAppendRow(std::move(row)); } delegate()->peerListRefreshRows(); } static constexpr auto kInvited = Row::State::Invited; const auto reorder = [&] { - const auto count = reorderIfInvitedBeforeIndex; + const auto count = reorderIfInvitedBefore; if (count <= 0) { return false; } const auto row = delegate()->peerListRowAt( - reorderIfInvitedBeforeIndex - 1).get(); + reorderIfInvitedBefore - 1).get(); return (static_cast(row)->state() == kInvited); }(); if (reorder) { @@ -1059,6 +1066,26 @@ void MembersController::updateRow( return static_cast(row).state() != kInvited; }); } + if (checkPosition) { + checkRowPosition(checkPosition); + } else if (addedToBottom) { + const auto real = resolvedRealCall(); + if (real && real->joinedToTop()) { + const auto proj = [&](const PeerListRow &other) { + const auto &real = static_cast(other); + return real.speaking() + ? 2 + : (&real == addedToBottom) + ? 1 + : 0; + }; + delegate()->peerListSortRows([&]( + const PeerListRow &a, + const PeerListRow &b) { + return proj(a) > proj(b); + }); + } + } } bool MembersController::allRowsAboveAreSpeaking(not_null row) const { @@ -1159,7 +1186,7 @@ void MembersController::checkRowPosition(not_null row) { // All force muted at the bottom, but 'row' still above others. ? (&real == row.get() ? 1ULL : 0ULL) // All not force-muted lie between raised hands and speaking. - : (std::numeric_limits::max() - 2); + : (kTop - 2); }; const auto projForOther = [&](const PeerListRow &other) { const auto &real = static_cast(other); diff --git a/Telegram/SourceFiles/data/data_group_call.cpp b/Telegram/SourceFiles/data/data_group_call.cpp index 835c825ace..2bd8eebf25 100644 --- a/Telegram/SourceFiles/data/data_group_call.cpp +++ b/Telegram/SourceFiles/data/data_group_call.cpp @@ -262,6 +262,7 @@ void GroupCall::applyCallFields(const MTPDgroupCall &data) { } _joinMuted = data.is_join_muted(); _canChangeJoinMuted = data.is_can_change_join_muted(); + _joinedToTop = !data.is_join_date_asc(); setServerParticipantsCount(data.vparticipants_count().v); changePeerEmptyCallFlag(); _title = qs(data.vtitle().value_or_empty()); @@ -738,6 +739,10 @@ bool GroupCall::canChangeJoinMuted() const { return _canChangeJoinMuted; } +bool GroupCall::joinedToTop() const { + return _joinedToTop; +} + ApiWrap &GroupCall::api() const { return _peer->session().api(); } diff --git a/Telegram/SourceFiles/data/data_group_call.h b/Telegram/SourceFiles/data/data_group_call.h index 0219aa99ec..4731dcd4da 100644 --- a/Telegram/SourceFiles/data/data_group_call.h +++ b/Telegram/SourceFiles/data/data_group_call.h @@ -104,6 +104,7 @@ public: void setJoinMutedLocally(bool muted); [[nodiscard]] bool joinMuted() const; [[nodiscard]] bool canChangeJoinMuted() const; + [[nodiscard]] bool joinedToTop() const; private: enum class ApplySliceSource { @@ -158,6 +159,7 @@ private: bool _joinMuted = false; bool _canChangeJoinMuted = true; bool _allParticipantsLoaded = false; + bool _joinedToTop = false; }; diff --git a/Telegram/ThirdParty/tgcalls b/Telegram/ThirdParty/tgcalls index e80667a343..384a5e4d78 160000 --- a/Telegram/ThirdParty/tgcalls +++ b/Telegram/ThirdParty/tgcalls @@ -1 +1 @@ -Subproject commit e80667a343b62f6b8b2c3e0a828222096a497990 +Subproject commit 384a5e4d78bfaf45af7e0edf7c2ce630aff6be73