mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Respect raise_hand_rating in participants list.
This commit is contained in:
parent
4d8ac05d28
commit
50265afe93
1 changed files with 121 additions and 31 deletions
|
@ -127,9 +127,15 @@ public:
|
||||||
[[nodiscard]] bool speaking() const {
|
[[nodiscard]] bool speaking() const {
|
||||||
return _speaking;
|
return _speaking;
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] crl::time speakingLastTime() const {
|
||||||
|
return _speakingLastTime;
|
||||||
|
}
|
||||||
[[nodiscard]] int volume() const {
|
[[nodiscard]] int volume() const {
|
||||||
return _volume;
|
return _volume;
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] uint64 raisedHandRating() const {
|
||||||
|
return _raisedHandRating;
|
||||||
|
}
|
||||||
|
|
||||||
void addActionRipple(QPoint point, Fn<void()> updateCallback) override;
|
void addActionRipple(QPoint point, Fn<void()> updateCallback) override;
|
||||||
void stopLastActionRipple() override;
|
void stopLastActionRipple() override;
|
||||||
|
@ -242,6 +248,8 @@ private:
|
||||||
Ui::Animations::Simple _activeAnimation; // For icon cross animation.
|
Ui::Animations::Simple _activeAnimation; // For icon cross animation.
|
||||||
Ui::Animations::Simple _arcsAnimation; // For volume arcs animation.
|
Ui::Animations::Simple _arcsAnimation; // For volume arcs animation.
|
||||||
QString _aboutText;
|
QString _aboutText;
|
||||||
|
crl::time _speakingLastTime = 0;
|
||||||
|
uint64 _raisedHandRating = 0;
|
||||||
uint32 _ssrc = 0;
|
uint32 _ssrc = 0;
|
||||||
int _volume = Group::kDefaultVolume;
|
int _volume = Group::kDefaultVolume;
|
||||||
bool _sounding = false;
|
bool _sounding = false;
|
||||||
|
@ -317,7 +325,12 @@ private:
|
||||||
const Data::GroupCall::Participant *participant);
|
const Data::GroupCall::Participant *participant);
|
||||||
void removeRow(not_null<Row*> row);
|
void removeRow(not_null<Row*> row);
|
||||||
void updateRowLevel(not_null<Row*> row, float level);
|
void updateRowLevel(not_null<Row*> row, float level);
|
||||||
void checkSpeakingRowPosition(not_null<Row*> row);
|
void checkRowPosition(not_null<Row*> row);
|
||||||
|
[[nodiscard]] bool needToReorder(not_null<Row*> row) const;
|
||||||
|
[[nodiscard]] bool allRowsAboveAreSpeaking(not_null<Row*> row) const;
|
||||||
|
[[nodiscard]] bool allRowsAboveMoreImportantThanHand(
|
||||||
|
not_null<Row*> row,
|
||||||
|
uint64 raiseHandRating) const;
|
||||||
Row *findRow(not_null<PeerData*> participantPeer) const;
|
Row *findRow(not_null<PeerData*> participantPeer) const;
|
||||||
|
|
||||||
[[nodiscard]] Data::GroupCall *resolvedRealCall() const;
|
[[nodiscard]] Data::GroupCall *resolvedRealCall() const;
|
||||||
|
@ -379,21 +392,23 @@ void Row::updateState(const Data::GroupCall::Participant *participant) {
|
||||||
setState(State::Invited);
|
setState(State::Invited);
|
||||||
setSounding(false);
|
setSounding(false);
|
||||||
setSpeaking(false);
|
setSpeaking(false);
|
||||||
|
_raisedHandRating = 0;
|
||||||
} else if (!participant->muted
|
} else if (!participant->muted
|
||||||
|| (participant->sounding && participant->ssrc != 0)) {
|
|| (participant->sounding && participant->ssrc != 0)) {
|
||||||
setState(participant->mutedByMe ? State::MutedByMe : State::Active);
|
setState(participant->mutedByMe ? State::MutedByMe : State::Active);
|
||||||
setSounding(participant->sounding && participant->ssrc != 0);
|
setSounding(participant->sounding && participant->ssrc != 0);
|
||||||
setSpeaking(participant->speaking && participant->ssrc != 0);
|
setSpeaking(participant->speaking && participant->ssrc != 0);
|
||||||
|
_raisedHandRating = 0;
|
||||||
} else if (participant->canSelfUnmute) {
|
} else if (participant->canSelfUnmute) {
|
||||||
setState(participant->mutedByMe
|
setState(participant->mutedByMe
|
||||||
? State::MutedByMe
|
? State::MutedByMe
|
||||||
: State::Inactive);
|
: State::Inactive);
|
||||||
setSounding(false);
|
setSounding(false);
|
||||||
setSpeaking(false);
|
setSpeaking(false);
|
||||||
|
_raisedHandRating = 0;
|
||||||
} else {
|
} else {
|
||||||
setState(participant->raisedHandRating
|
_raisedHandRating = participant->raisedHandRating;
|
||||||
? State::RaisedHand
|
setState(_raisedHandRating ? State::RaisedHand : State::Muted);
|
||||||
: State::Muted);
|
|
||||||
setSounding(false);
|
setSounding(false);
|
||||||
setSpeaking(false);
|
setSpeaking(false);
|
||||||
}
|
}
|
||||||
|
@ -507,12 +522,19 @@ void Row::setVolume(int volume) {
|
||||||
void Row::updateLevel(float level) {
|
void Row::updateLevel(float level) {
|
||||||
Expects(_blobsAnimation != nullptr);
|
Expects(_blobsAnimation != nullptr);
|
||||||
|
|
||||||
|
const auto spoke = (level >= GroupCall::kSpeakLevelThreshold)
|
||||||
|
? crl::now()
|
||||||
|
: crl::time();
|
||||||
|
if (spoke && _speaking) {
|
||||||
|
_speakingLastTime = spoke;
|
||||||
|
}
|
||||||
|
|
||||||
if (_skipLevelUpdate) {
|
if (_skipLevelUpdate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level >= GroupCall::kSpeakLevelThreshold) {
|
if (spoke) {
|
||||||
_blobsAnimation->lastSoundingUpdateTime = crl::now();
|
_blobsAnimation->lastSoundingUpdateTime = spoke;
|
||||||
}
|
}
|
||||||
_blobsAnimation->blobs.setLevel(level);
|
_blobsAnimation->blobs.setLevel(level);
|
||||||
}
|
}
|
||||||
|
@ -1003,14 +1025,16 @@ void MembersController::updateRow(
|
||||||
auto reorderIfInvitedBeforeIndex = 0;
|
auto reorderIfInvitedBeforeIndex = 0;
|
||||||
auto countChange = 0;
|
auto countChange = 0;
|
||||||
if (const auto row = findRow(now.peer)) {
|
if (const auto row = findRow(now.peer)) {
|
||||||
if (now.speaking && (!was || !was->speaking)) {
|
|
||||||
checkSpeakingRowPosition(row);
|
|
||||||
}
|
|
||||||
if (row->state() == Row::State::Invited) {
|
if (row->state() == Row::State::Invited) {
|
||||||
reorderIfInvitedBeforeIndex = row->absoluteIndex();
|
reorderIfInvitedBeforeIndex = row->absoluteIndex();
|
||||||
countChange = 1;
|
countChange = 1;
|
||||||
}
|
}
|
||||||
updateRow(row, &now);
|
updateRow(row, &now);
|
||||||
|
if ((now.speaking && (!was || !was->speaking))
|
||||||
|
|| (now.raisedHandRating != (was ? was->raisedHandRating : 0))
|
||||||
|
|| (!now.canSelfUnmute && was && was->canSelfUnmute)) {
|
||||||
|
checkRowPosition(row);
|
||||||
|
}
|
||||||
} else if (auto row = createRow(now)) {
|
} else if (auto row = createRow(now)) {
|
||||||
if (row->speaking()) {
|
if (row->speaking()) {
|
||||||
delegate()->peerListPrependRow(std::move(row));
|
delegate()->peerListPrependRow(std::move(row));
|
||||||
|
@ -1045,39 +1069,107 @@ void MembersController::updateRow(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MembersController::checkSpeakingRowPosition(not_null<Row*> row) {
|
bool MembersController::allRowsAboveAreSpeaking(not_null<Row*> row) const {
|
||||||
if (_menu) {
|
|
||||||
// Don't reorder rows while we show the popup menu.
|
|
||||||
_menuCheckRowsAfterHidden.emplace(row->peer());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Check if there are non-speaking rows above this one.
|
|
||||||
const auto count = delegate()->peerListFullRowsCount();
|
const auto count = delegate()->peerListFullRowsCount();
|
||||||
for (auto i = 0; i != count; ++i) {
|
for (auto i = 0; i != count; ++i) {
|
||||||
const auto above = delegate()->peerListRowAt(i);
|
const auto above = delegate()->peerListRowAt(i);
|
||||||
if (above == row) {
|
if (above == row) {
|
||||||
// All rows above are speaking.
|
// All rows above are speaking.
|
||||||
return;
|
return true;
|
||||||
} else if (!static_cast<Row*>(above.get())->speaking()) {
|
} else if (!static_cast<Row*>(above.get())->speaking()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Someone started speaking and has a non-speaking row above him. Sort.
|
return false;
|
||||||
const auto proj = [&](const PeerListRow &other) {
|
}
|
||||||
if (&other == row.get()) {
|
|
||||||
// Bring this new one to the top.
|
bool MembersController::allRowsAboveMoreImportantThanHand(
|
||||||
return 0;
|
not_null<Row*> row,
|
||||||
} else if (static_cast<const Row&>(other).speaking()) {
|
uint64 raiseHandRating) const {
|
||||||
// Bring all the speaking ones below him.
|
Expects(raiseHandRating > 0);
|
||||||
return 1;
|
|
||||||
} else {
|
const auto count = delegate()->peerListFullRowsCount();
|
||||||
return 2;
|
for (auto i = 0; i != count; ++i) {
|
||||||
|
const auto above = delegate()->peerListRowAt(i);
|
||||||
|
if (above == row) {
|
||||||
|
// All rows above are 'more important' than this raised hand.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
const auto real = static_cast<Row*>(above.get());
|
||||||
|
const auto state = real->state();
|
||||||
|
if (state == Row::State::Muted
|
||||||
|
|| (state == Row::State::RaisedHand
|
||||||
|
&& real->raisedHandRating() < raiseHandRating)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MembersController::needToReorder(not_null<Row*> row) const {
|
||||||
|
// All reorder cases:
|
||||||
|
// - bring speaking up
|
||||||
|
// - bring raised hand up
|
||||||
|
// - bring muted down
|
||||||
|
|
||||||
|
if (row->speaking()) {
|
||||||
|
return !allRowsAboveAreSpeaking(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto rating = row->raisedHandRating();
|
||||||
|
if (!rating && row->state() != Row::State::Muted) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (rating > 0 && !allRowsAboveMoreImportantThanHand(row, rating)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const auto index = row->absoluteIndex();
|
||||||
|
if (index + 1 == delegate()->peerListFullRowsCount()) {
|
||||||
|
// Last one, can't bring lower.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto next = delegate()->peerListRowAt(index + 1);
|
||||||
|
const auto state = static_cast<Row*>(next.get())->state();
|
||||||
|
if ((state != Row::State::Muted) && (state != Row::State::RaisedHand)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!rating && static_cast<Row*>(next.get())->raisedHandRating()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MembersController::checkRowPosition(not_null<Row*> row) {
|
||||||
|
if (_menu) {
|
||||||
|
// Don't reorder rows while we show the popup menu.
|
||||||
|
_menuCheckRowsAfterHidden.emplace(row->peer());
|
||||||
|
return;
|
||||||
|
} else if (!needToReorder(row)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Someone started speaking and has a non-speaking row above him.
|
||||||
|
// Or someone raised hand and has force muted above him.
|
||||||
|
// Or someone was forced muted and had can_unmute_self below him. Sort.
|
||||||
|
static constexpr auto kTop = std::numeric_limits<uint64>::max();
|
||||||
|
const auto proj = [&](const PeerListRow &other) {
|
||||||
|
const auto &real = static_cast<const Row&>(other);
|
||||||
|
return real.speaking()
|
||||||
|
// Speaking 'row' to the top, all other speaking below it.
|
||||||
|
? (&real == row.get() ? kTop : (kTop - 1))
|
||||||
|
: (real.raisedHandRating() > 0)
|
||||||
|
// Then all raised hands sorted by rating.
|
||||||
|
? real.raisedHandRating()
|
||||||
|
: (real.state() == Row::State::Muted)
|
||||||
|
// 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<uint64>::max() - 2);
|
||||||
};
|
};
|
||||||
delegate()->peerListSortRows([&](
|
delegate()->peerListSortRows([&](
|
||||||
const PeerListRow &a,
|
const PeerListRow &a,
|
||||||
const PeerListRow &b) {
|
const PeerListRow &b) {
|
||||||
return proj(a) < proj(b);
|
return proj(a) > proj(b);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1342,9 +1434,7 @@ void MembersController::rowClicked(not_null<PeerListRow*> row) {
|
||||||
auto saved = base::take(_menu);
|
auto saved = base::take(_menu);
|
||||||
for (const auto peer : base::take(_menuCheckRowsAfterHidden)) {
|
for (const auto peer : base::take(_menuCheckRowsAfterHidden)) {
|
||||||
if (const auto row = findRow(peer)) {
|
if (const auto row = findRow(peer)) {
|
||||||
if (row->speaking()) {
|
checkRowPosition(row);
|
||||||
checkSpeakingRowPosition(row);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_menu = std::move(saved);
|
_menu = std::move(saved);
|
||||||
|
|
Loading…
Add table
Reference in a new issue